Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

YAML::XS, YAML::Syck and boolean values

by walkingthecow (Friar)
on Jul 26, 2013 at 04:54 UTC ( #1046452=perlquestion: print w/ replies, xml ) Need Help??
walkingthecow has asked for the wisdom of the Perl Monks concerning the following question:

Forgive me if I have overlooked some documentation on this.

Looking at the YAML 1.1 spec, I see that anything matching this regexp:

y|Y|yes|Yes|YES|n|N|no|No|NO |true|True|TRUE|false|False|FALSE |on|On|ON|off|Off|OFF
is considered a boolean.

I have the following structure in my .yaml file:
- name: Bob Johnson active: true happy: false - name: Bill Johnson active: true happy: true - name: Frank Johnson active: false happy: false - name: George Johnson active: false happy: true
I have the following code:
#!/usr/bin/env perl use strict; use warnings; use YAML::XS qw(LoadFile); use Data::Dumper; my $data = LoadFile('/tmp/test.yaml'); print Dumper($data);

The code for YAML::Syck is the same other than the fact that I am using YAML::Syck rather than YAML::XS.

Here are the results from each:

YAML::XS
$VAR1 = [ { 'name' => 'Bob Johnson', 'active' => 1, 'happy' => '' }, { 'happy' => ${\$VAR1->[0]{'active'}}, 'active' => ${\$VAR1->[0]{'active'}}, 'name' => 'Bill Johnson' }, { 'name' => 'Frank Johnson', 'active' => ${\$VAR1->[0]{'happy'}}, 'happy' => ${\$VAR1->[0]{'happy'}} }, { 'active' => ${\$VAR1->[0]{'happy'}}, 'name' => 'George Johnson', 'happy' => ${\$VAR1->[0]{'active'}} } ];
YAML::Syck
$VAR1 = [ { 'active' => 'true', 'happy' => 'false', 'name' => 'Bob Johnson' }, { 'name' => 'Bill Johnson', 'happy' => 'true', 'active' => 'true' }, { 'active' => 'false', 'happy' => 'false', 'name' => 'Frank Johnson' }, { 'name' => 'George Johnson', 'happy' => 'true', 'active' => 'false' } ];
The values from YAML::Syck are fine with me, somewhat. I was hoping for 1/0, but no big deal really, since true/false will evaluate fine. However, the results from YAML::XS are not exactly what I was expecting. I was hoping for each key to have its own value, not for keys to point to the values of other keys, which is what it seems that this is doing. Is there some way with YAML::XS to have boolean values? It seems to me that if a key has the same value as another key, then that key's value just becomes a reference for the other key's value.

Comment on YAML::XS, YAML::Syck and boolean values
Select or Download Code
Re: YAML::XS, YAML::Syck and boolean values
by Loops (Hermit) on Jul 26, 2013 at 06:05 UTC
    This is surely just an internal optimization to save memory. It's not significant in this test data, but it could be for large duplicate structures. It should be transparent in any case that matters, no? The structure is readonly, so there is no danger in updates at least.
    my $val = $data->[1]->{active}; print Dumper $val;
    Prints:
    $VAR1 = 1;
    Which I admit is hardly worth the space it took to quote... Worst case there is this:
    my $clean = [ map {{%$_}} @$data ]; print Dumper \$clean;
    Outputs:
    $VAR1 = \[ { 'name' => 'Bob Johnson', 'active' => 1, 'happy' => '' }, { 'name' => 'Bill Johnson', 'active' => 1, 'happy' => 1 }, { 'name' => 'Frank Johnson', 'active' => '', 'happy' => '' }, { 'name' => 'George Johnson', 'active' => '', 'happy' => 1 } ];
Re: YAML::XS, YAML::Syck and boolean values
by tobyink (Abbot) on Jul 26, 2013 at 07:26 UTC

    You really want YAML::XS to behave more like YAML::Syck here? Because I think YAML::XS's behaviour is more correct than YAML::Syck's. Demonstration:

    #!/usr/bin/env perl use strict; use warnings; use YAML::XS (); use YAML::Syck (); my $data = do { local $/; <DATA> }; print "With YAML::XS...\n"; my $xs = YAML::XS::Load($data); for my $person (@$xs) { print "$person->{name} is happy\n" if $person->{happy}; } print "With YAML::Syck...\n"; my $syck = YAML::Syck::Load($data); for my $person (@$syck) { print "$person->{name} is happy\n" if $person->{happy}; } __DATA__ - name: Bob Johnson active: true happy: false - name: Bill Johnson active: true happy: true - name: Frank Johnson active: false happy: false - name: George Johnson active: false happy: true

    YAML::Syck claims that Bob and Frank Johnson are happy!

    It's true that the ${\$VAR1->[0]{'active'}} bits in the Data::Dumper output look funny, but that seems to be an optimization that YAML::XS is applying; using the same SV structure (if you don't know what an SV structure is, perlguts probably has more info than you want) to represent all booleans in the whole output data structure.

    I can achieve a similar effect using Data::Alias (note that Data::Alias is broken in Perl 5.18):

    #!/usr/bin/env perl use strict; use warnings; use Data::Alias; use Data::Dumper; my $false = !! 0; my $true = !! 1; my (@foo, @bar); alias $foo[0] = $false; alias $bar[0] = $false; alias $foo[1] = $true; alias $bar[1] = $true; print Dumper \@foo, \@bar;
    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
Re: YAML::XS, YAML::Syck and boolean values
by Anonymous Monk on Jul 26, 2013 at 07:30 UTC

    Is there some way with YAML::XS to have boolean values?

    No, not without patching it

    update :

    Well , it could be possible through a simple DEFINE , there is YAML_PLAIN_SCALAR_STYLE which uses the perl true/false constants of PL_sv_yes, PL_sv_no, PL_sv_undef but I don't see how you activate it -- its all C to me

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1046452]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (13)
As of 2014-07-23 19:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (152 votes), past polls