bv has asked for the wisdom of the Perl Monks concerning the following question:
So I found what I believe to be a bug in YAML::Any, specifically in the Dump function, but I suspect that the nearly identical code in DumpFile, Load, and LoadFile are also buggy. The intention of the code in question is to apply the settings of the $YAML::Option global options to the chosen implementation of YAML (in my case, YAML::XS). Here is the code, with my debug statements marked:
sub Dump { no strict 'refs'; my $implementation = __PACKAGE__->implementation; my $debug; # My own debug variable for my $option (@dump_options) { my $var = "$implementation\::$option"; $debug = $var if $var =~/UseCode/; #the option I wish to set my $value = $$var; local $$var; # <-- PROBLEM! Local to "for", not "sub" $$var = defined $value ? $value : ${"YAML::$option"}; # Here I print out the option in each iteration of the loop print STDERR "$debug = $$debug\n"; } # And the final value: print STDERR "FINAL: $debug = $$debug\n"; return &{"$implementation\::Dump"}(@_); }
My test code:
#!/usr/bin/perl use strict; use warnings; use YAML::Any; local $YAML::UseCode=1; my $input = sub { print "Enter a value: "; return chomp (my $ret = <>); }; print Dump $input; __END__ Name "YAML::UseCode" used only once: possible typo at test.pl line 7. YAML::XS::UseCode = 1 YAML::XS::UseCode = YAML::XS::UseCode = YAML::XS::UseCode = YAML::XS::UseCode = YAML::XS::UseCode = YAML::XS::UseCode = YAML::XS::UseCode = YAML::XS::UseCode = YAML::XS::UseCode = YAML::XS::UseCode = YAML::XS::UseCode = YAML::XS::UseCode = YAML::XS::UseCode = YAML::XS::UseCode = FINAL: YAML::XS::UseCode = --- !!perl/code '{ "DUMMY" }'
The "Name used only once" warning is not the issue, since I get the same warning when setting $YAML::XS::UseCode directly, and the output is what I would expect (The output of B::Deparse on the CODE reference);
What I believe is the issue is that each global option is localized within the for loop, and immediately returns to its previous value upon the next iteration. What I need is a solution to localize the value such that it stays set for the function call that is returned in the last line. So my questions are twofold:
Thanks much! My environment: YAML-0.70, YAML-LibYAML-0.32, "This is perl, v5.10.0 built for i486-linux-gnu-thread-multi"
UPDATE: My workaround is to use YAML::Any's implementation() method and cheat with strict refs:
#!/usr/bin/perl use warnings; use YAML::Any; local ${YAML::Any->implementation()."::UseCode"}=1; # can't use strict before this because of refs use strict;
@_=qw; Just another Perl hacker,; ;$_=q=print "@_"= and eval;
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Bug in YAML::Any - What to do?
by ikegami (Patriarch) on Dec 15, 2009 at 00:01 UTC | |
|
Re: Bug in YAML::Any - What to do?
by zwon (Abbot) on Dec 14, 2009 at 23:30 UTC | |
|
Re: Bug in YAML::Any - What to do?
by Anonymous Monk on Dec 14, 2009 at 23:23 UTC | |
by ikegami (Patriarch) on Dec 14, 2009 at 23:43 UTC | |
by Anonymous Monk on Dec 14, 2009 at 23:25 UTC |