Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

Reference as a hash key

by Anonymous Monk
on Aug 25, 2009 at 15:48 UTC ( #791114=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Given that this works:

my $ref = []; my %hash; $hash{$ref} = 1; print keys %hash;

and returns "ARRAY(0x.....)", my question is; is this likely to bring about some tutting and shaking of heads in experienced perl developers?

(Some background: I needed a method of storing which anonymous arrays out of a large number had been examined, and quickly checking that store to see if one had already been examined.)

Replies are listed 'Best First'.
Re: Reference as a hash key
by bluestar (Novice) on Aug 25, 2009 at 16:15 UTC
    Why not rather have a data structure like this:
    $array_ref = [ { array_ref => $ref, has_been_examined => 1, }, { array_ref => $ref, has_been_examined => 1, }, etc ... ]
    By doing this you are able to associate additional custom metadata to each anonymous array.
Re: Reference as a hash key
by AnomalousMonk (Canon) on Aug 25, 2009 at 16:05 UTC
    It depends on just what you want to do with the keys of your hash.

    As you see, all hash keys are stringified, so the keys can never again be used as references (the original references are unaffected). However, they are stringified uniquely because each reference has a unique address, so I see no problem with using the string representation to flag that a particular array has been handled.

    Of course, if the referent of a reference is destroyed, the hash key corresponding to it is unaffected! You have to take care of this on your own. And remember: if references are destroyed and new ones created, old reference addresses may be re-used!

    Actually, I think I would tend to use something like bluestar's suggestion in Re: Reference as a hash key: it's more general and flexible, probably more maintainable.


    1. Added note about reference destruction.
    2. Added endorsement of bluestar's suggestion.
Re: Reference as a hash key
by LanX (Chancellor) on Aug 25, 2009 at 16:43 UTC
    As long as no anonymous arrays are destroyed and defined during your examination there shouldn't be a risk of collisions of equally stringified refs.

    I assume you know that the stringification of a reference is a one-way-function ... if you ever need to know the corresponding ref you should consider, writing  $hash{$ref} = $ref; instead.

    (or using something like Tie::RefHash)

    Cheers Rolf

      hmm just a (maybe not too) strange thought ...

      ... if these are just plain arr-refs and not already blessed obj-refs you might use a simple hack to flag them with attributes :

      You may bless them into a package _SEEN_ and check it with ref ! 8)

      DB<1> $arr=[] DB<2> bless $arr,"_SEEN_" DB<3> p ref $arr _SEEN_ DB<4> bless $arr,"_UNSEEN_" DB<5> p ref $arr _UNSEEN_

      You wont have any collision risk and you can safely pass the refs around with the information attached without caring about any extra %seen hash.

      Cheers Rolf

      UPDATE: I just noticed that (unfortunately) there is no way to "unbless" references in perl afterwards! :-(

      You may write bless $arr,"ARRAY" to try undoing blessing but even if ref now returns "ARRAY" it's NOT the same as "unblessing" and may cause subtle bugs ... just check it with Scalar::Util::blessed $arr ! Pity!

Re: Reference as a hash key
by goeb (Pilgrim) on Aug 25, 2009 at 16:01 UTC
    I don't really know about using the reference as a hash key, someone else will have to answer this question. There is however Scalar::Util refaddr function which you could use to explicitely use the reference's address as a key to a hash (or even as an array index). Edit: Better use hashes for this, performance with an array might be much worse since the memory addresses can get very huge.
Re: Reference as a hash key
by ssandv (Hermit) on Aug 25, 2009 at 16:04 UTC

    Well, your use case probably isn't as clearly stated as you think it is. If you're saying that you need to quickly check to see if a given anonymous array has been examined, why not reserve the zeroth element of each array for a "I've been examined!" indicator?

    If, on the other hand, you mean that you need to check the entire set of arrays to see which ones have been examined, then you're still going to traverse the whole set of arrays, and a hash doesn't save you, because the long time isn't in the lookup, it's in the traversal.

Re: Reference as a hash key
by Sewi (Friar) on Aug 25, 2009 at 17:39 UTC
    Each reference is unique, so it's a valid key. I don't know any reason why your solution shouldn't work, I also did something like this some time ago and it worked. I can't see any reason why you shouldn't use a ref as a key, but always remember that tie'ing the whole thing won't work.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://791114]
Approved by AnomalousMonk
[Corion]: stevieb: Yeah, but I don't follow guitar players enough... I never got Prince and I don't think I could recognize his play style. I can recognize Santana and Nile Rodgers, but that's about it, and not really deep knowledge I think ;)
[stevieb]: Jeff Healey cut of My guitar gently weeps
[stonecolddevin]: you don't recognize Prince. Prince tells you it's him.
[erix]: Alvin Lee (Ten Years After) played a jazzguitar ("Big Red"), a good warm sound
[stonecolddevin]: I think Stevie Ray is one of maybe 2 or 3 people that could take a Hendrix song and make you go "...huh. this is close." https://open. 0UVM9trirBK5s1xBwL oVhZ
[stonecolddevin]: https://open. 0UVM9trirBK5s1xBwL oVhZ rather
[Corion]: Sadly I must go to bed now :-| See y'all!
[erix]: I really loved/love this "Recorded Live" record, 1973 (yes, I'm that old)
[stonecolddevin]: goodnight Corion
[erix]: cya Corion :)

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (6)
As of 2017-06-22 21:33 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (531 votes). Check out past polls.