0

I'm looking for a solution for using complex keys (arbitrary references) as hash keys, except that they perform deep comparison on the keys as opposed to reference comparison.

I am looking for a function preferably in a core module that serializes arbitrary references (possibly excluding subroutine and typeglob references) to strings in such a way that they can be reconstituted later.

 my @complex_key = qw[key1 key2];
 my %hash;
 $hash{serialize([@complex_key])} = 'value';

  deserialize((keys %hash)[0]);
   # should deeply equal [@complex_key]
0

1 Answer 1

5

There's no need to serialize all that data just to have a (potentially enormous) hash key. Instead, take the checksum of the data structure and use that for a key. Store the original key as part of the value.

Here's an example using perl5i to do the deep checksum.

use perl5i::2;
$hash{@stuff->mo->checksum} = {
    key   => \@stuff,
    value => 'value'
};

my $value = $hash{@stuff->mo->checksum}{value};
my $key   = $hash{@stuff->mo->checksum}{key};

You can wrap this in a little class to make it more convenient.

sub get {
    my $self = shift;
    my $key  = shift;

    return $self->{$key->mo->checksum}{value};
}

sub set {
    my $self = shift;
    my($key, $val) = @_;

    $self->{$key->mo->checksum} = $val;

    return;
}

sub each {
    my $self = shift;
    my $code = shift;

    my $val;
    while( (undef, $val) = each %$self ) {
        $code->($val->{key}, $val->{value});
    }

    return;
}

$obj->set(\@stuff, "value");
my $value = $obj->get(\@stuff);

$obj->each( func($key, $val) {
    say "$key -> $val\n";
}
Sign up to request clarification or add additional context in comments.

2 Comments

The Perl5i module is really cool, but I'm not sure I need an entire meta object extension to construct a deep checksum of an arbitrary value. I checked the implementation of checksum and it uses Data::Dumper to get a string representation of arbitrary values and to sort keys in hashes. What is the advantage of that approach over setting $Storable::canonical = 1, and then hashing the resulting serialization of the data structure?
@GregoryNisbet perl5i brings all sorts of other value to your fingertips, and $foo->mo->checksum is already implemented and tested. But any serialization + checksum technique will work. The point is the technique, not the implementation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.