Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Odd (to me) case of wrongly guessing context

by ibm1620 (Beadle)
on May 20, 2013 at 21:41 UTC ( #1034411=perlquestion: print w/ replies, xml ) Need Help??
ibm1620 has asked for the wisdom of the Perl Monks concerning the following question:

In the following, db_select_row() returns an array. Originally there was no "// croak ..." and it worked fine (the correct value of mx_registered_process_id was 2). When I added "// croak...", the process_id was set to 1!! Am I correct in guessing that the "defined-or" convinced Perl that I wanted the returned array to be interpreted in scalar context? What would have been a better way to do it?
my ($mx_registered_process_id) = db_select_row( $dbh, "SELECT process_id FROM mx_registered_process " . "WHERE process_name = '$process'" ); # // croak "Process '$process' not defined in mx_registered_process\n" +;

Comment on Odd (to me) case of wrongly guessing context
Download Code
Re: Odd (to me) case of wrongly guessing context
by rjt (Deacon) on May 20, 2013 at 21:51 UTC

    Your problem comes from the combination of the my ... with the defined-or operator. It's an operator precedence issue: put (my ...) in brackets. You can also use the low-precedence or operator, but only if you can guarantee that 0 will never be a valid return.

    sub context { wantarray ? (qw/foo bar/) : -1 } my ($not_foo) = context() // say "Whoops"; say $not_foo; (my ($foo) = context()) // say "Whoops"; say $foo; # This works if context() can never return 0 my ($also_foo) = context() or say "Whoops"; say $also_foo;
      Note that you can never trigger the right hand side of
      ( my ($ar) = () ) // die "Undefined array in scalar context";
      In other words, you can safely remove the // croak part.
      لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

        Ah yes, quite right. I missed that in my haste.

        OP, the function you're calling doesn't appear to be standard DBI, so I can't advise you (the OP) on how to handle exceptions, but in general, it will probably be one of the following:

        • The function might die() on error; use eval
        • It may return an empty list, in which case your $mx_registered_process_id will be undef (but undef might also indicate something else, such as a NULL column, so be careful; assign the function return to an intermediary @array if that's the case).
        • It may use a package scalar to hold error values (which is set to undef if there was no error.

        Again, this is all just speculative, since I don't know the semantics of your db_select_row() function.

        Good catch, but this works

        DB<106> (my ($ar) = () ) || print "bla" bla DB<108> (my ($ar) = (1) ) || print "bla" => 1 DB<109> (my ($ar) = (0) ) || print "bla" => 1 DB<110> (my ($ar) = (undef) )|| print "bla" => 1 DB<111> (my ($ar) = (undef,undef) )|| print "bla" => 2

        list-assignment in scalar context counts and the count is always defined. (see also goatse-operator for comparison.)

        DB<119> scalar ( my ($ar) = () ) => 0

        so only empty-list is 0 and false.

        But I'm not sure if I'm in favour of such constructs...

        Cheers Rolf

        ( addicted to the Perl Programming Language)

Re: Odd (to me) case of wrongly guessing context
by LanX (Canon) on May 20, 2013 at 22:14 UTC
    rjt already answered your question, allow me a hint for the future:

    In such cases B::Deparse is your friend

    perl -MO=Deparse,-p -e 'my ($not_foo) = context() // print "Whoops"' (my($not_foo) = (context() // print('Whoops')));

    Used -p to add extra parens to highlight precedence.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: Odd (to me) case of wrongly guessing context
by ig (Vicar) on May 20, 2013 at 22:29 UTC
    Am I correct in guessing that the "defined-or" convinced Perl that I wanted the returned array to be interpreted in scalar context?

    You are correct. From perlop:

    Thus, EXPR1 // EXPR2 returns the value of EXPR1 if it's defined, otherwise, the value of EXPR2 is returned. (EXPR1 is evaluated in scalar context, EXPR2 in the context of // itself).

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1034411]
Approved by davido
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: (6)
As of 2014-12-26 22:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (176 votes), past polls