in reply to Re: wantarray - surprise behaviour
in thread wantarray - surprise behaviour

Not having used wantarray before, I looked it up in the docs. It says:

Returns true if the context of the currently executing subroutine is looking for a list value.

Does that mean the context where the wantarray is, or where the function call is?

If it's where wantarray is, print provides the list context, doesn't it?

If it's where the function is called as a hash value, couldn't you're example just as easily be (1, $a), instead of (1, @a)?

Now that I'm thinking about it, maybe you're saying (1, @a) because the last statement in blah() is a print statment and providing list context?

Just trying to wrap my mind completely around this, too.

TheEnigma

Replies are listed 'Best First'.
Re^3: wantarray - surprise behaviour
by ikegami (Patriarch) on Aug 31, 2004 at 20:10 UTC
    Does that mean the context where the wantarray is, or where the function call is?

    Where the function call is.

    If it's where the function is called as a hash value

    blah() is not called "as a hash value". It is called while building a list (which eventually will be assigned to a hash.) For example:

    %hash = (a => 'b', 'c', d => split(//, 'ef'));

    results in

    $hash{'a'} = 'b' $hash{'c'} = 'd' $hash{'e'} = 'f'

    It's useful to think of the () as an operator creating an anonymous list.

    couldn't you're example just as easily be (1, $a), instead of (1, @a)?

    Yes, a scalar can be be provided when an a list is expected. However, I used @a because an array behaves differently in scalar and list contexts. (It returns the number of elements in the former, and the list of elements in the latter.)

      It's useful to think of the () as an operator creating an anonymous list.

      No it isn't. () is just about getting things to parse correctly. The list comes from the comma operators , and =>.

        I've seen this said before, but

        P:\test>perl -MO=Deparse -e"@a = 1,2,3,4,5; print @a" @a = 1, '???', '???', '???', '???'; print @a; -e syntax OK P:\test>perl -e"@a = 1,2,3,4,5; print @a" 1 P:\test>perl -MO=Deparse -e"@a = (1,2,3,4,5); print @a" @a = (1, 2, 3, 4, 5); print @a; -e syntax OK P:\test>perl -e"@a = (1,2,3,4,5); print @a" 12345

        Empirically, that suggests that the parens are, at least in some cases, required to build a list.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
        No, the list *doesn't* come from the comma. It comes from the assignment:
        sub foo { $c = wantarray; print $c ? "A" : defined $c ? "S" : "V" } (foo(), foo(), foo()); print "\n"; $v = (foo(), foo(), foo()); print "\n"; @v = (foo(), foo(), foo()); print "\n"; __END__ VVV VVS AAA
Re^3: wantarray - surprise behaviour
by hardburn (Abbot) on Aug 31, 2004 at 20:35 UTC

    Adding to what others have said, it might be easier to get your head around this concept if you think of arrays and hashes as both being fancy kinds of lists. You can assign one to the other and maintain the same information (unlike assigning a list to a scalar, which only gives you the length of the list).

    @a = ( 1, 2, 3, 4 ); %h = @a; print $h{1}; # prints 2 print $h{3}; # prints 4 print $h{2}; # prints nothing (undefined hash element) @b = %h; print $b[2]; # Unknown, since the hash doesn't maintain order # Exact behavior is undefined, and often # changes between perl versions. $ref = { @a }; # $ref gets a hash ref, but the anonoymous ref # is built with an array.

    "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

      (not sure of the proper etiquette when replying to several replies, so I replied to the last one)

      Thanks to all for your help fellow monks!

      blah() is not called "as a hash value".

      Sorry, ikegami, I knew as I was writing that, that it wasn't worded very well.

      But anyway...
      So it's the fact that the blah() call is in a list, that gives the function list context, and therefore, wantarray returns true.

      TheEnigma

Re^3: wantarray - surprise behaviour
by trammell (Priest) on Aug 31, 2004 at 20:04 UTC
    In this example, "the context of the currently executing subroutine" ("blah()") is:
    ( 1 => blah() )
    It has nothing to do with what is happening inside blah().
Re^3: wantarray - surprise behaviour
by saberworks (Curate) on Aug 31, 2004 at 20:06 UTC
    wantarray refers to where the function was called from.
    Returns true if the context of the currently executing subroutine is looking for a list value. Returns false if the context is looking for a scalar. Returns the undefined value if the context is looking for no value (void context).
    When you call a subroutine, all arguments are sent in list context, thus the way to get the arguments back inside the sub is using the ($arg1, $arg2) = @_;

    It's always list context, even if the list only contains a single value.
Re^3: wantarray - surprise behaviour
by shemp (Deacon) on Aug 31, 2004 at 20:08 UTC
    Wnatarray()s return is always the context of the call of the subroutine that it is in. Note also that wantarray always returns a scalar value (0, 1, undef)

    What happens inside the subroutine that wantarray() is in is absolutely irrelevant to what wantarray() reports.

    There are 3 contexts that a subroutine can be called in:

    blah(); # void $x = blah(); # scalar @x = blah(); # list
    Anything you can dream up that can be assigned into fits into one of those categories. But dont trick yourself into thinking something like this will try a list assignment:
    my $x = []; # $x is now an (empty) arrayref $x = blah(); # $x is a scalar - wantarray reports 0
    So, even though $x is an arrayref, an arrayref is NOT a list, its a scalar. A reference to be specific.