Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

List context or not?

by sguazt (Novice)
on Mar 12, 2001 at 23:52 UTC ( #63927=perlquestion: print w/ replies, xml ) Need Help??
sguazt has asked for the wisdom of the Perl Monks concerning the following question:

Suppose you have this code:
my %hash = ( a => 1, b => 2, c => 3, d => 4 ); sub foo { my $n = ($_[0]) ? $_[0] : keys %hash; return (keys %hash)[0 .. ($n - 1)]; # return %hash keys from 0 to $n + - 1 } my $bar = &foo(); # want to return the number of keys of %hash print "$bar\n";
You'll notice that the value printed isn't the num of keys but a key itself. (Suppose the code from the beginning to end of foo function is located in an external package!!) But foo return a list; the value returned by foo is evaluated in an array context and so 'Why does not it work?'

Comment on List context or not?
Download Code
Re: List context or not?
by yakko (Friar) on Mar 13, 2001 at 00:06 UTC
    Since foo() returns a list, why not assign it to a list:
    my @bar=foo(); print "@bar\n";
    To get the number of keys returned by foo(), it'd be:
    my $baz=scalar(@bar);
    (Update: the "wantarray" answers are probably better, I'm a young grasshopper learning, blah blah blah. :o)

    --
    Me spell chucker work grate. Need grandma chicken.

(tye)Re: List context or not?
by tye (Cardinal) on Mar 13, 2001 at 00:08 UTC

    What does a "list slice" return in a scalar context? It isn't actually documented (though some make outrageous claims that it is).

    But it isn't the number of items in the slice. If you want a count returned in the case of scalar context, then use wantarray to code for that.

            - tye (but my friends call me "Tye")
      What does a "list slice" return in a scalar context? It isn't actually documented (though some make outrageous claims that it is).
      It's not outrageous. Stop being so disingenuous. perldata clearly says:
      @days{'a','c'} # same as ($days{'a'},$days{'c'})
      If you want a language defined by a formal specification, rather than by example, you know where to find Java or Ada or PL/1.

      And as always, patches welcome. Turn them in, or shut up about this.

      -- Randal L. Schwartz, Perl hacker

        I don't really care that the behavior of a list slice in a scalar context isn't documented. What I mind is the silly claim that the comment "same as" in a one-line example about a hash slice (or even an array slice) is supposed to be considered as documentation about how a list slice behaves in a scalar context.

        By your logic, the line just below that:     %days        # (key1, val1, key2, val2 ...)
        indicates that %days in a scalar context should return the "last" value of the hash. Or is it only when the magic "same as" words are written that it should become obvious to me that "same to the point of returning the same value in a scalar context" is meant, but not, for example, "same to the point of meaning the same thing when passed to localtime()" or any other possible overextensions of the term "same as"?

        So unless you are accepting patches for your logic, I have none to submit. q-:

                - tye (but my friends call me "Tye")
Re: List context or not?
by baku (Scribe) on Mar 13, 2001 at 00:37 UTC

    the value returned by foo is evaluated in an array context

    Actually, the = (assignment operator) imposes the context of the 'lvalue' onto the 'rvalue.' That means that since the left side of the = is a scalar ($bar), the right side is evaluated in a scalar context.

Re: List context or not?
by buckaduck (Chaplain) on Mar 13, 2001 at 01:04 UTC
    I think you may be confusing a list with an array. An array does return the number of elements when used in a scalar context. But a list does not. A list returns the last item in a list. Thus:
    $a = (10, 20, 30); # $a = 30 @nums = (10, 20, 30); $a = @array; # $a = 3
    And I think your subroutine is returning a list, not an array.

    buckaduck

      I have apparently been confused for quite some time. I used to think that a list and an array were the same. The Camel book says, however, that
      @stuff = ("one", "two", "three");
      assigns the entire list value to array @stuff, but:
      $stuff = ("one", "two", "three");
      assigns only the value three to variable $stuff.

      So contrary to what I had thought a list is not an array. It is sort of a proto-array, a thingy that one might likely turn into an array but is not there yet.

      There is also something called a reference to an anonymous array. One creates it using brackets as in:

      $arrayref = ["one", "two", "three"];
      Since lists are comma-separated lists of values the text inside the brackets above is an example of an anonymous array which is also a list. However, lists are not in general arrays, they have to be assigned to arrays.

      when used in a scalar context. A list returns the last item in a list.

      Lots of different types of lists return lots of different things in scalar contexts. The most common behavior is to return the last item.

              - tye (but my friends call me "Tye")
        I'm not aware of different types of lists having varying behavior in scalar context. Are there some examples?

        My original response was based on the documentation in perldata - "If you evaluate a named array in a scalar context, it returns the length of an array. (Note that this is not true of lists, which return the last value, like the C comma operator, nor of built-in functions, which return whatever they feel like returning.)"

        buckaduck

Re: List context or not?
by dws (Chancellor) on Mar 13, 2001 at 01:17 UTC
    If you want the subroutine to be sensitive to whether it's being called in a scalar context or not, use wantarray.
    sub foo { my $n = $_[0] ? $_[0] : keys %hash; return wantarray() ? (keys %hash)[0..($n-1)] : $n }
    I assume your example is contrived. If not, you might check to see whether there are at least $_[0] keys.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://63927]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (16)
As of 2014-11-24 15:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (143 votes), past polls