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

why does
$ perl -e 'print (my ($rec) = undef);' print nothing, but $ perl -e 'print "return=" . (my ($rec) = undef);' print return=1
shouldn't the first print 1 ?

aside from the "why would you do that?" questions....

thanks!

update (broquaint): put <code> tags in apporpriate place and added formatting

Replies are listed 'Best First'.
Re: undef var
by sgifford (Prior) on Jul 03, 2003 at 20:42 UTC

    The first is being evaluated in a list context, because print takes a list, but the second is evaluted in a scalar context because you're concatenating this. In a scalar context, a list evaluates to the number of elements it contains.

    If you change the contexts in your examples, you'll get the opposite results:

    perl -e 'print scalar(my ($rec) = undef);' perl -e 'print "return=",(my ($rec) = undef);'
    The first explicitly asks for a scalar context, and prints 1. The second stays in print's list context and so prints nothing (well, just return=).
      In a scalar context, a list evaluates to the number of elements it contains.

      More precisely, in a scalar context a list assignment returns the number of items on the right-hand side.

      If anyone ever says of Perl "a list in a scalar context", then you know they've fallen victim to a very common misconception. They'll usually end that with "returns the last item in the list", but that wouldn't have made sense in this case.

      The fact is that there is no one rule for what you get when you "put a list in a scalar context". Some would even say that you can't put a list into a scalar context. I prefer to say that it depends on what the "list" is. Because I don't feel that "list" is a well-defined term in Perl.

      There are a great many "things that would return a list if used in a list context" and each of them can have their own rule for what they return if used in a scalar context. The most common is "last item", though exactly what an "item" is can be a bit tricky to define. (:

                      - tye
(jeffa) Re: undef var
by jeffa (Bishop) on Jul 03, 2003 at 20:32 UTC
    B::Deparse is your friend (although it really doesn't reveal too much with these one-liners):
    $ perl -MO=Deparse -e 'print (my ($rec) = undef);' print my($rec) = undef; -e syntax OK $ perl -MO=Deparse -e 'print "return=" . (my ($rec) = undef);' print 'return=' . (my($rec) = undef); -e syntax OK
    The first one-liner is printing the result of assigning undef to $rec and the second appends that result to a string.

    UPDATE:
    Nope ... i wasn't quite correct on this one. Thanks for clearing things up sgifford and tye.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: undef var
by Anonymous Monk on Jul 04, 2003 at 09:18 UTC
    My guess is that the . operator forces the return into string context. In the default context, perl prints the result of assigning undef to my ($rec), in string context, it prints whether the assignment of undef to my ($rec) succeeded or failed. Succeed being 1 and fail being 0.