http://qs321.pair.com?node_id=1158673

nysus has asked for the wisdom of the Perl Monks concerning the following question:

Monks, I'm seeing some very odd behavior I think might be a bug (in Moose?) but maybe I'm missing something more basic.

So I've got this line of code:

$event->polished_data->{start} = $event->start_time;

$event is an object created with Moose, polished_data is an attribute and isa HashRef. $event->start_time is a Time::Piece object. Yes, I am copying the Time::Piece from one part of the object to another.

Here's where the weirdness comes in. After the assignment, when I Dumper the event, sometime the value indexed by the start is the Time::Piece object and and the value of $event->start_time looks like this: $VAR1->{'polished_data'}{'start'}. What's really weird is the rest of the time (about 50% of the time), $event->start_time is the Time::Piece object and the indexed value in the hash is $VAR1->{'polished_data'}{'start'}. Witness:

$VAR1 = bless( { 'event_id' => '2927', 'post_id' => 0, 'polished_data' => { 'start' => bless( [ 0, 0, 19, 28, 2, 116, 1, 87, 1, 1459206000, 1 ], 'Time::Piec +e' ), }, 'start_time' => $VAR1->{'polished_data'}{'start'}, }, 'Event' ); $VAR1 = bless( { 'start_time' => bless( [ 0, 0, 18, 11, 3, 116, 1, 101, 1, 1460412000, 1 ], 'Time::Piece' ), 'polished_data' => { 'start' => $VAR1->{'start_time'} +, }, }, 'Event' );

If anyone can explain what's going on and help me workaround this issue, I'd greatly appreciate it.

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: Very odd behavior assigning Time::Piece object to hash reference inside of an object
by tangent (Parson) on Mar 24, 2016 at 02:14 UTC
    The behaviour you are seeing is actually a feature of Data::Dumper - the $VAR1->{'polished_data'}{'start'} is simply pointing to the first occurrence of what is exactly the same thing. It does this with all references:
    use Data::Dumper; use Time::Piece; my $tp = gmtime; my @array = (200,400); my $data = { 'one' => { 'tp' => $tp, 'array' => \@array, }, 'two' => { 'tp' => $tp, 'array' => \@array, }, }; print Dumper $data; Output: $VAR1 = { 'one' => { 'array' => [ [ 200, 400 ] ], 'tp' => bless( [ 35, 2, 2, 24, 2, '116', 4, 83, 0, 1458784955, 0 ], 'Time::Piece' ) }, 'two' => { 'array' => $VAR1->{'one'}{'array'}, 'tp' => $VAR1->{'one'}{'tp'} } };
    To prevent it from doing that you can set Deepcopy:
    use Data::Dumper; $Data::Dumper::Deepcopy = 1; ... Output: $VAR1 = { 'one' => { 'array' => [ [ 200, 400 ] ], 'tp' => bless( [ 48, 10, 2, 24, 2, '116', 4, 83, 0, 1458785448, 0 ], 'Time::Piece' ) }, 'two' => { 'array' => [ [ 200, 400 ] ], 'tp' => bless( [ 48, 10, 2, 24, 2, '116', 4, 83, 0, 1458785448, 0 ], 'Time::Piece' ) } };
      Thank you for clearing this up.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks