develooper Front page | perl.perl5.porters | Postings from October 2002

Re: Collections

Thread Previous | Thread Next
From:
Slaven Rezic
Date:
October 1, 2002 08:03
Subject:
Re: Collections
Message ID:
871y7aurwq.fsf@vran.herceg.de
Damien Neil <neild@misago.org> writes:

> On Mon, Sep 30, 2002 at 11:18:37AM -0700, Brian Ingerson wrote:
> > I want to write this:
> > 
> >     while ($i++ < 100000) {
> >         $dice1 = int(rand(6)) + 1;
> >         $dice2 = int(rand(6)) + 1;
> >         $roll = [$dice1, $dice2];
> >         $rolls->{$roll}++;                  <--
> >     }
> >     use Data::Dumper;
> >     print Dumper $rolls;
> 
> An alternate viewpoint:
> 
> I'm happy writing the above replacing the "<--" marked line with
> 
>           $rolls->{"$dice1 $dice2"}++;
> 
> I have no problems with the the hash key of a ref being based on
> the ref's address rather than the contents of the ref.  What I
> *would* like, occasionally, is the ability to get that ref back
> out of the hash.

With Devel::Pointer, this seems to be possible:

use Devel::Pointer;

$x1 = [1,2,3,4];
$x2 = {5,6,7,8};
$y{$x1} = "foo";
$y{$x2} = "bar";

foreach (keys %y) {
    my($type,$addr) = $_ =~ /(.*)\((.*)\)/;
    my $ref = &{"unsmash_" . {ARRAY => "av",
			      HASH  => "hv"}->{$type}}(hex($addr));
    require Data::Dumper; print STDERR "Line " . __LINE__ . ", File: " . __FILE__ . "\n" . Data::Dumper->new([$ref],[])->Indent(1)->Useqq(1)->Dump; # XXX
}
__END__

returns:

Line 27, File: /tmp/v.pl
$VAR1 = {
  7 => 8,
  5 => 6
};
Line 27, File: /tmp/v.pl
$VAR1 = [
  1,
  2,
  3,
  4
];

> 
> This has the advantage of being far less likely to break existing
> code.  If you example above did what you want, I suspect a great
> deal of code would break.
> 
> Consider the following scenario:
> 
>   my $dog = Dog::Poodle->new;
>   $names{$dog} = "Fido";
> 
>   $dog->legs(3);          # Alas, a tragic tea trolley accident.
> 
>   print $names{$dog};     # ...which has made Fido a new dog, it seems.
> 
>   my @dogs = keys %names; # And what dog now lives in the hash key?
> 
> At the moment, modifying $dog will not affect its hash value.  Change
> hashes to do a deep equivalence test on keys, and you get very
> surprising results.

That's why Brian suggested a HASH() method which would be called only
once and the result would be attached to the object. So modifying the
object wouldn't modify the hash value.

Regards,
	Slaven

-- 
Slaven Rezic - slaven.rezic@berlin.de

    tkruler - Perl/Tk program for measuring screen distances
    http://ptktools.sourceforge.net/#tkruler

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About