Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Data::Diver polluting $!

by philkime (Beadle)
on Nov 01, 2012 at 10:29 UTC ( [id://1001793]=perlquestion: print w/replies, xml ) Need Help??

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

This snippet:
use Data::Diver qw( Dive ); my $ref = {'original' => {'default' => 'result'}}; print Dive($ref, 'original', 'default'), "\n"; die;
outputs:
result
Can't use string ("default") as a SCALAR ref while "strict refs" in use at /usr/lib/perl5/site_perl/5.14/Data/Diver.pm line 91.
        ...propagated at /tmp/test.pl line 7.
That is, simple Dive() use pollutes $! due to a test in the code. "no strict refs" doesn't fix it. It means that any die(), croak() etc. reports this even when you don't want it to. Am I missing something or perhaps there is an alternative non auto-vivifying module?

Replies are listed 'Best First'.
Re: Data::Diver polluting $!
by roboticus (Chancellor) on Nov 01, 2012 at 12:23 UTC

    philkime:

    The documentation, in the $! section, states:

    $! If used numerically, yields the current value of the C "errno" variable, or in other words, if a system or library call fails, it sets this variable. This means that the value of $! is meaningful only immediately after a failure...

    A bit earlier, just after the Error Variables heading, it mentions that:

    The variables $@, $!, $^E, and $? contain information about different types of error conditions ... They correspond to errors detected by the Perl interpreter, C library, operating system, or an external program, respectively.

    So the long and short of it is that using the value of $! at any time other than just after a failed operation involving the C library is a bug.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: Data::Diver polluting $@
by Anonymous Monk on Nov 01, 2012 at 10:49 UTC

    No, Data::Diver is not polluting $@

    Don't use die like that, give die an argument or use exit

      Although I mostly agree, I'll try to upload a new release of Data::Diver in short order that adds local($@) any places that it uses eval.

      And thanks for mentioning $@ as it saved me from figuring out what was really going on, because I was immediately pretty sure that the problem wasn't with $!, but I didn't immediately realize what the real problem was.

      - tye        

        Here is another, docs lead me to believe these should all work but Dive doesn't

        #!/usr/bin/perl -- use strict; use warnings; use Data::Diver qw/ Dive DiveRef DiveDie /; sub say { print @_, "\n"; } say DiveDie( DiveRef( { qw/ key val / }, \'key' ) ); say DiveDie( Dive( { qw/ key val / }, \'key' ) ); __END__ SCALAR(0x3f90cc) Key not present in hash using SCALAR(0xabe37c) on HASH(0x3f90dc) (from + Data::Diver).

        Problem is in sub Dive, when you're testing if $ref is a hash with eval, you forgot the 1, this line
        -        } elsif(  eval { exists $ref->{$key} }  ) {
        +        } elsif(  eval { exists $ref->{$key}; 1 }  ) {

        I've tested it it works , your test suite doesn't test for this so maybe add to Data-Diver-1.0101/t/base.t the following

        ok( 'val', Dive( { qw/ key val / }, \'key' ) ); ok( 'val', Dive( { qw/ key val / }, 'key' ) ); ok( 'val', DiveVal( { qw/ key val / }, \'key' ) ); ok( 'val', DiveVal( { qw/ key val / }, 'key' ) );

        Also remember the Replacment for Data::Diver due missing license

        For the honor

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (None)
    As of 2024-04-25 03:54 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      No recent polls found