It seems that Perl can only have strings as a hash. (Was this changed in a specific version of Perl?) This greatly limits the ability to use strings as a key. What if I want an object or array to be a key? In Python, it is easy to use an array, a tuple, and other objects that can be compared, like dict keys. Perl has the ability to compare things, such as arrays for equality, so I don’t understand why they cannot be used as keys for a display type.
Is there a way to use any type of key in Perl? Is there a module that provides this?
Does AFAIK Perl just build keys?
package Foo; use Moose; use overload ('""' => \&stringify); sub stringify { return "xxx"; } package main; use v5.10; use Data::Dump 'pp'; my $foo = Foo->new; my $hash = {$foo => 'bar'}; say pp($hash); // { xxx => "bar" }
That way you can also use whatever you want as a hash key. See also this thread on Perl Monks .
For equality, take a look at the equality operators in perlop . The operator is ==compared numerically, the operator is eqcompared line by line. This means, for example, that it is (4, 2) == (1, 2)true (like scalar (4, 2)is 2), which may be unexpected for you.
==
eq
(4, 2) == (1, 2)
scalar (4, 2)
2
, , Perl , , . Perl . , Perl , .
Perl . , , :
$key = ['a', 'b']; $hash{$key} = [ $key, $val ]; # Prevents the key from being freed. print $hash{$key}[1];
Perl , , , , . .
, , -, . . ( ).
, .
sub key{ "@_" } # Overly simplistic? $hash{key('a', 'b')} = $val; print $hash{key('a', 'b')};
, CPAN : Tie::Hash::StructKeyed. , . / .
Yes it is, use field characters ( Hash :: Util :: FieldHash for 5.10+ and Hash :: Util :: FieldHash :: Compat before 5.10) to register your hashes as field characters, and you can use any link (and , therefore, any object) as a key for these hashes (it essentially captures the link and provides logic for processing CLONEing by threads and garbage collection using garbage), for example:
use Hash::Util qw/fieldhashes/; fieldhashes \my (%foo, %bar, %baz); my %data = (a => 1, b => 2, c => 3); my $stuff = {t => 2, u => 3, l => 9}; $foo{\%data} = 'x'; $foo{$stuff} = 'a'; $bar{\%data} = 'y'; $bar{$stuff} = 'b'; $baz{\%data} = 'z'; $baz{$stuff} = 'c'; print "$foo{\%data} $bar{\%data} $baz{\%data}\n"; print "$foo{$stuff} $bar{$stuff} $baz{$stuff}\n";