in reply to Re: perlsub question..
in thread perlsub question..

thank you. that makes sense. few lines down in perlsub, i also read this paragraph:

If no return is found and if the last statement is an expression, its +value is returned. If the last statement is a loop control structure +like a foreach or a while, the returned value is unspecified. The emp +ty sub returns the empty list.

the last two sentences look wrong to me. tried this:

D:\>perl -MData::Dumper -e "sub x{1 for 1..5};@y=x();print 'ha' if def +ined @y" ha

so the return value is certainly defined.

The empty sub returns the empty list. that depends on what it's return context is though, not necessarily a empty list..

Replies are listed 'Best First'.
Re^3: perlsub question..
by naikonta (Curate) on Jun 23, 2007 at 19:19 UTC
    the last two sentences look wrong to me. tried this:
    D:\>perl -MData::Dumper -e "sub x{1 for 1..5};@y=x();print 'ha' if def +ined @y" ha
    There's a few things to note:
    • It's said that If the last statement is a loop control structure like a foreach or a while, the returned value is unspecified. "Unspecified" is not equal to "undefined", it means Perl can't guarantee what such subs would return. But in your case, it returns a list with a single empty element.
      $ perl -MData::Dumper -e 'sub x{1 for 1..5};@y=x();print Dumper(\@y)' $VAR1 = [ '' ];
    • You don't use defined function for aggregate variables such as arrays and hashes because, Use of "defined" on aggregates (hashes and arrays) is deprecated. It used to report whether memory for that aggregate has ever been allocated. This behavior may disappear in future versions of Perl. So, it prints "ha" when you check the defined-ness of the array @y because it has been allocated some memory.
    • Most (if not all) of the time you want to check whether an array or a hash have element, thus say ... if @y; instead of ... if defined @y;. Eventhough, it would still print "ha" because the array has, indeed, an element which is empty (see point 1).
    Finally, consider the following snippets:
    $ perl -wle 'sub x{};@y=x(); print "array" if @y' (nothing) $ perl -wle 'sub x{};%y=x();print "hash" if %y' (nothing) $ perl -wle 'sub x{1..3};@y=x(); print "array" if @y' array $ perl -wle 'sub x{a => 1};%y=x();print "hash" if %y' hash

    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

Re^3: perlsub question..
by Jenda (Abbot) on Jun 23, 2007 at 18:50 UTC

    The docs did not say the returned value is undefined, they say it's unspecified! It means that you should not expect the value to make any sense, it could be anything. You could get the 1 you got, you could get an undef, you could get an 'gotcha dude!' string, you could get anything. The result is not specified.

Re^3: perlsub question..
by shmem (Chancellor) on Jun 23, 2007 at 20:22 UTC

    What do you load Data::Dumper for? Had you used it, you had found:

    perl -e "sub x{ 1 for 1..5 };@y=x(); print Dumper(\@y) if defined @y" $VAR1 = [ '' ];

    Looks pretty much "unspecified". Finding out what that sub actually returned is left as an exercise to the reader :-)

    that depends on what it's return context is though, not necessarily a empty list..
    Yes. Return values are evaluated in the caller's context at subroutine return, which may happen implicitly at the subroutine end.

    No, subs always return a list. Sometimes it's empty, sometimes it has only one value. It's up to the caller how it treats that list, and it's up to the sub which elements it returns if it evaluates the context in which it is executed..

    This discussion makes me marvel again upon how well written the perl documentation is...

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}