in reply to (tye)Re: ref, no, maybe?
in thread ref, no, maybe?

tye said:
The problem with "HASH" eq ref($r) is that it will fail if $r is a reference to a blessed hash. Why would you want to refuse to do useful hash stuff on something just because it is blessed?
Because a blessed hashref is not a hashref; it's an object. The whole point of an object is encapsulation; to quote The Camel, "In Perl culture, by contrast, you're expected to stay out of someone's home because you weren't invited in, not because there are bars on the windows" (pg. 278, 2nd ed.). i.e., Just because a blessed hashref is a hashref - with modifiable values - at heart doesn't mean i should manipulate it. That could break an object in spectacular ways.

Replies are listed 'Best First'.
(tye)Re4: ref, no, maybe?
by tye (Sage) on Jan 11, 2001 at 06:44 UTC

    Yes, you shouldn't go messing with the hash behind my blessed ref when I give it to you as an object. But that isn't what I'm talking about.

    You have some function that does something useful with a hash. I have an object that consists of a blessed reference to a hash. Inside the code for that class, I have to mess with my own hash. Well, if this manipulation of my own hash would be made easier by using your useful function, then why shouldn't I be allowed to do that?

    Now, it'd be nice, being inside the class code, if I could get a non-blessed reference to my hash. But I can't. If that one thing were different, then I wouldn't mind the use of "HASH" eq ref($r) nearly so much.

            - tye (but my friends call me "Tye")
      I'm not sure this is a good example.

      If you're inside your own class, you ought to know if it's a blessed hash or not without calling ref on it.

      Not that I haven't violated that rule a few times... but we could all come up with outrageous examples where this doesn't work. We're just too smart for our own good; let's leave it at that.

        Sorry, you misunderstood me. The problem is that I write a module, Tye::IsCool, that implements objects as blessed references to a hash. Well, you already wrote a module called Chromatic::HashMangler which is just the cat's pajamas and does interesting things to hashes.

        Well, inside of sub Tye::IsCool::AmazeNAstound() I want to use your module to do complex things to the hash that implements my object. But your module does:

        sub Chromatic::HashMangler::DeepMagic { my $refToHashToMangle= shift; croak "You suck" unless "HASH" eq ref($refToHashToMangle);
        so I'm screwed because you won't get "HASH"; you'll get "Tye::IsCool" and croak.

        Its a been a long day for me (and it isn't over yet), so I hope that makes more sense. :-}

                - tye (but my friends call me "Tye")
      As the author of this hypothetical function, i take the stance that it is Not My Problem(tm). My flawless (haha!) docs clearly state that the function can take a plain scalar or a hashref; not a hash-based object. I contend that the burden falls on the you, the caller, to put the data in the condition my function expects.

      Now if Perl doesn't provide a good way for you to do that, that is another argument entirely.

        "I object! Your honor, to use the 'It's documented so it isn't a bug' defense, the defendant also has to document why the 'bug' wasn't just 'fixed'." ;-)

        So do you write "I'm too lazy to use UNIVERSAL::isa() -- too many keystrokes"? "I have a religious and/or philosophical objection to object implementations using my module"?

        If your documentation says "hash ref" and not "hash ref that isn't blessed", then not handling a "blessed hash ref" (which is, by the way, still a "hash ref") is a violation of your own documentation. q-:

        If your documentation says "an unblessed hash ref", then I have to ask "Why??". Are you now going to start checking tied(%$self) and croaking if the reference is to a tied hash? Is there some problem with using UNIVERSAL::isa()? A very simple change makes your module more useful. Is there some down side to this? I don't see one. I didn't see you mention one. What is your objection to this?

        And there are other cases that your theoretical module "breaks". For example, Win32::TieRegistry exposes the Win32 "Registry" as a huge hash of hashes. So the majority of things that you'd want to do can be done by just dealing with a huge hash of hashes. But for a few advanced options, the reference to this huge virtual hash of hashes is also blessed into a package so you can use it directly to make method calls.

        So it really sucks when a module, for example, to search down a hash of hashes searching for something (kind of like File::Find for hash trees) can't be used on this hash of hashes that I did all this work to make available to millions of Win32 Perl users.

        There you made me say it. Happy now?

                - tye (but my friends call me "Tye")