Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Re: Confused as to why the "casting context" is mis-behaving

by philipbailey (Chaplain)
on Oct 20, 2010 at 11:47 UTC ( #866292=note: print w/replies, xml ) Need Help??

in reply to Confused as to why the "casting context" is mis-behaving

This is one of those times when there is a difference between a list and an array in Perl. It seems hard to produce a concise definition of the difference, but to a first approximation an array is a list with a name (such as @a in your examples). So qw(a b c d e) is a list which you have assigned to @a.

What you have exposed is that in scalar context, a array and list (both containing the same data) have different values. The value, in scalar context, of an array, is the number of elements. The value, in scalar context, of a list, is the last item in that list.

Update. See perlfaq4
  • Comment on Re: Confused as to why the "casting context" is mis-behaving

Replies are listed 'Best First'.
Re^2: Confused as to why the "casting context" is mis-behaving
by thargas (Deacon) on Oct 20, 2010 at 13:02 UTC

    Hmm. Please point to documentation. Your description of what's happening jibes with what we see, but I had the same impression as the original poster, i.e. that this was not the way it would work.

    If there is no documentation, and I couldn't find any, then there needs to be. I'm not sure where to put it though. I looked in perlop under comma and perldata under slices.

    In fact, under perltrap, I found:

    ? Comma operator in scalar context gives scalar context to args The comma operator in a scalar context is now guaranteed to give scalar context to its arguments. @y= ('a','b','c'); $x = (1, 2, @y); print "x = $x\n"; # Perl4 prints: x = c # Thinks list context interpolates list # Perl5 prints: x = 3 # Knows scalar uses length of list
    Which I would take to be documentation to the contrary.

    I'm confused.

      from perlop:

      Comma Operator
      Binary "," is the comma operator. In scalar context it evaluates its left argument, throws that value away, then evaluates its right argument and returns that value. This is just like Cís comma operator.

      In list context, itís just the list argument separator, and inserts both its arguments into the list. These arguments are also evaluated from left to right.

      This is documented in perldata, though maybe not as clearly or concisely as one might hope.

      The first issue is whether a slice is a list or not, ruling out the possibility that it is an array.

      This isn't stated clearly, as one might hope, in Slices. In that section it is, at best, only hinted at by statements like:

      A slice accesses several elements of a list, an array, or a hash simultaneously using a list of subscripts. Itís more convenient than writing out the individual elements as a list of separate scalar values.


      Since you can assign to a list of variables, you can also assign to an array or hash slice.

      Perhaps the closest this section comes is:

      Since you can assign to a list of variables, you can also assig +n to an array or hash slice. @days[3..5] = qw/Wed Thu Fri/; @colors{'red','blue','green'} = (0xff0000, 0x0000ff, 0x00ff00); @folks[0, -1] = @folks[-1, 0]; The previous assignments are exactly equivalent to ($days[3], $days[4], $days[5]) = qw/Wed Thu Fri/; ($colors{'red'}, $colors{'blue'}, $colors{'green'}) = (0xff0000, 0x0000ff, 0x00ff00); ($folks[0], $folks[-1]) = ($folks[-1], $folks[0]);

      But this only states the exact equivalence in the case of assignment to a slice. It doesn't state that there is an exact equivalence in all cases.

      There are other indications. In Context one finds (emphasis mine):

      or slice, which is just a list anyway)

      And in Variable names one finds:

      @days[3,4,5] # same as ($days[3],$days[4],$days[5]) @days{'a','c'} # same as ($days{'a'},$days{'c'})

      So, perldata does not clearly, concisely and definitively state that slices and lists are equivalent in the obvious place (Slices), but none the less,if one reads carefully, I think this is the conclusion one would come to.

      If one accepts that a slice is equivalent to a list, then this leaves the question of what a list evaluates to in scalar context.

      In Scalar values one finds (emphasis mine):

      If you evaluate an array in scalar context, it returns the length of the 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.)

      The Note about lists is equivalent to the statement: If you evaluate a list in scalar context, it returns the last value, like the C comma operator.

      Thus we have the two relevant facts documented, more or less:

      • A slice is a list
      • A list, evaluated in scalar context, returns the last value

      These together predict the observed behavior.

      The quote from perltrap is interesting but I don't find it inconsistent with any of the above. It really should be covered under Context. They take care to state the context of the righthand side in the case of assignment to a list, but don't cover this less obvious case.

        You don't find the quote from perltrap interesting? Not even the fact that they have effectively the same assignment (from a list to a scalar) and claim that the result will be the length of the list? I.E. that note in perltrap is wrong, at least for those versions of perl that I have access to.

        I do find that interesting because that's the first documentation I found when looking for what the documented behaviour would be. My method was look to grep perltoc for slice and context and then look in the pages it pointed at.

        If this isn't going to be documented under the docs for slice (IMHO the correct place), then the other places need to be correct. Or we'll have people reporting bugs because they can't find the correct documentation.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://866292]
[Eily]: LanX as a matter of fact this is one of the occasions where bretons see themselves as french indeed :P
[erix]: but surely Hinault was Breton not french?
[erix]: s/$/ :)/
[ovedpo15]: regex question - how can I delete everything until string "here" (including "here") for all the string (not until the first pattern)? for example a/here/b/here/c will return "/c"
[LanX]: Eily is Breton?
[erix]: 'spas

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (12)
As of 2018-07-17 13:21 GMT
Find Nodes?
    Voting Booth?
    It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?

    Results (366 votes). Check out past polls.