Data-Printer icon indicating copy to clipboard operation
Data-Printer copied to clipboard

Incorrect output with tied hashes

Open Ovid opened this issue 3 years ago • 0 comments

Hi there. With tied hashes, the output appears to be incorrect. I've included a _data_printer method in my class and all values are reported as being the same as the first value:

For this minimal test case, I've created a simple tied hash which calls scalar reverse on all hash values before storing them. I then dump two identical hashes, with the first hash being tied. The second hash is built with the values of the first. The output is:

{
    first    4321,
    second   var{first},
    third    var{first}
} (tied to Tie::Me::Up)
{
    first    4321,
    second   "DCBA",
    third    "?ftw"
}

Here's my sample code:

#!/usr/bin/env perl

use warnings;
use Data::Printer;

package Tie::Me::Up {
    use v5.20.0;
    use feature 'signatures';
    no warnings 'experimental::signatures';

    sub TIEHASH ( $class, $generator ) {
        return bless {
            generator => $generator,
            hash      => {},
        }, $class;
    }

    sub FETCH ( $self, $key ) {
        return $self->{hash}{$key};
    }

    sub STORE ( $self, $key, $value ) {
        $self->{hash}{$key} = $self->{generator}->($value);
    }

    sub DELETE ( $self, $key ) {
        return delete $self->{hash}{$key};
    }

    sub CLEAR ($self) {
        $self->{hash} = {};
    }

    sub EXISTS ( $self, $key ) {
        return exists $self->{hash}{$key};
    }

    sub FIRSTKEY ($self) {
        keys %{ $self->{hash} };    # reset each() iterator
        each %{ $self->{hash} };
    }

    # lastkey is here for documentation, but we don't use it
    sub NEXTKEY ( $self, $lastkey ) {
        return each %{ $self->{hash} };
    }

    sub SCALAR ($self) {
        return scalar keys %{ $self->{hash} };
    }

    sub _data_printer ( $self, @ ) {

        # it doesn't matter if I return a list or a hashref
        # return %{ $self->{hash} };
        return $self->{hash};
    }

    # DESTROY this is not needed
    # UNTIE this is not needed
}

sub munger {
    my ( $key, @args ) = @_;
    return "Stored: " . join '-', $key, @args;
}

tie my %hash, 'Tie::Me::Up', sub { return scalar reverse $_[0] };
$hash{first}  = '1234';
$hash{second} = 'ABCD';
$hash{third}  = 'wtf?';
my %hash_2 = (
    first  => $hash{first},
    second => $hash{second},
    third  => $hash{third},
);
p %hash;
p %hash_2;

Note that Tie::Me::Up includes several methods not needed for this example, but I wanted to be complete, in case you needed to test other scenarios.

Perl info (built via bog-standard perlbrew setup):

07:29:07 {main} ~/projects/perl/lazy-variables $ perl -v

This is perl 5, version 26, subversion 3 (v5.26.3) built for darwin-2level
(with 1 registered patch, see perl -V for more detail)

Ovid avatar Jun 30 '22 17:06 Ovid