Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
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 romping around the Monastery: (6)
As of 2014-07-30 04:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (229 votes), past polls