artist has asked for the wisdom of the Perl Monks concerning the following question:

Recently while studying Ruby Language, I noticed that we can use any type of object as a hash index. I think that, it is a very good feature. Do you see any advantages ? How that is possible with Perl? Can we say $hash{$object} = 'something'?
--Artist

20050520 Edit by Corion: Changed title from 'Hash Keys'

Replies are listed 'Best First'.
Re: Objects as hash keys?
by davido (Cardinal) on May 17, 2005 at 16:41 UTC

    You can, but it may or may not do what you think it's going to do. ...unless your expectations are in line with the documentation, of course.

    Putting an object reference in place as a hash key causes the reference to be stringified. Each instance of an object has a unique reference, so the stringification is unique. However, you cannot take a stringified reference and turn it back into a real reference. So if that is your intention, you're outta luck.

    However, it turns out that stringifying an object reference happens to be a convenient way of forming an internal object handle for inside out objects.


    Dave

Re: Objects as hash keys?
by jdporter (Paladin) on May 17, 2005 at 16:45 UTC
      Exactly, the feature. I feel that I can do more with Perl, after learning Ruby.
      package Person; sub new { my $class = shift; my $self = {_name => shift}; bless $self, $class; } 1; package Computer; sub new { my $class = shift; my $self = {_name => shift}; bless $self, $class; } package MP3Player; sub new { my $class = shift; my $self = {_name => shift}; bless $self, $class; } 1; package main; $c1 = Computer->new("Dell"); $c2 = Computer->new("Apple"); $m1 = MP3Player->new("IPOD"); $p1 = Person->new("artist"); $p2 = Person->new("jdporter"); use Tie::RefHash; tie %gift, 'Tie::RefHash'; $gift{$p1} = [$c1]; $gift{$p2} = [$c2,$m1]; foreach my $person (keys %gift){ print "Person: ", $person->{_name},"\n"; foreach my $gift (@{$gift{$person}}){ print "Gift\t", ref $gift,"\t", $gift->{_name},"\n"; } }
      --Artist
Re: Objects as hash keys?
by Transient (Hermit) on May 17, 2005 at 16:40 UTC
    package MyObj; sub new { bless {}, shift; } 1; --- #!/usr/bin/perl -w use MyObj; my %hash; my $a = MyObj->new(); my $b = MyObj->new(); $hash{$a} = "This is my Object A"; $hash{$b} = "This is my Object B"; print $a, "\n"; print $b, "\n"; print $_, " : ", $hash{$_}, "\n" foreach keys %hash; __END__ MyObj=HASH(0x2001b1fc) MyObj=HASH(0x2001b2e0) MyObj=HASH(0x2001b1fc) : This is my Object A MyObj=HASH(0x2001b2e0) : This is my Object B
    Looks like it can be done...

      One caveat:

      package MyObj; sub new { bless {}, shift; } sub test { print("test\n"); } package main; my $o = MyObj->new(); my %hash; $hash{$o} = "This is my object"; foreach (keys(%hash)) { print("$_\n"); # MyObj=HASH(0x1abefc0) print("$hash{$_}\n"); # This is my object $_->test(); # Can't locate object method "test" via package # "MyObj=HASH(0x1abefc0)" (perhaps you forgot to # load "MyObj=HASH(0x1abefc0)"?) at script.pl line 26 }
        Exactly my point.
        --Artist
Re: Objects as hash keys?
by gaal (Parson) on May 17, 2005 at 16:58 UTC
    It is possible in Perl6. L<S09/Hashes> states:
      To declare a hash that can take any object as a key rather than just a string, say something like:            my %hash is shape(Any); Likewise, you can limit the keys to objects of particular types:            my Fight %hash is shape(Dog;Cat); The standard Hash is just            my Any %hash is shape(Str); Note that any type used as a key must be intrinsically immutable, or it has to be able to make a copy that functions as an immutable key, or it has to have copy-on-write semantics. It is erroneous to change a key object’s value within the hash except by deleting it and reinserting it.