Does Perl have an associative array type that can have any types of keys?

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?

+5
source share
4 answers

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.

+3
source

, , 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')};
+3

, CPAN : Tie::Hash::StructKeyed. , . / .

+3

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";
+1
source

All Articles