rodd has asked for the wisdom of the Perl Monks concerning the following question:
my @arr; push @arr, { xx=>\99 } for 1..2; my $arr2 = YAML::XS::Load( YAML::XS::Dump( \@arr ) ); $arr2->[0]->{xx}='THIS VALUE IS MEANT TO CHANGE ONE ROW ONLY'; say "NO WAY!" if $arr2->[0]->{xx} eq $arr2->[1]->{xx}; # which prin +ts NO WAY!
I don't get it. In the for loop, doesn't \99 resolve to 2 different references to 2 different values (which is 99)? So why after dumping/loading, writing to row 0 also modifies the HASH in row 1?
Actually, if you view the YAML text generated by Dump():
--- - xx: &1 !!perl/ref =: 99 - xx: *1
This tells you there's an alias (*1 ==> &1) that makes both xx attributes point to the same place. The problem is that Load() seemingly treats the xx key as the same memory location, which is not remotely a decent interpretation of the serialized data-- "hold a reference to the same data" does not mean "we're in the same address".
I wish I could switch to JSON or another YAML module (YAML::Syck, YAML etc do not have the same behavior), but right now some serious production code depends on this YAML::XS (and the speed is nice too) hence no changes can be undertaken in the near future.
So I dove into the YAML::XS C code, but could not find the culprit:
https://github.com/ingydotnet/yaml-libyaml-pm/blob/master/LibYAML/perl_libyaml.c
Rod
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: YAML scalar ref strange behavior (JSON++)
by tye (Sage) on Jun 04, 2014 at 02:45 UTC | |
by rodd (Scribe) on Jun 04, 2014 at 14:33 UTC |