|Problems? Is your data what you think it is?|
Re: Scalars, Lists, and Arraysby Dominus (Parson)
|on Apr 13, 2001 at 04:41 UTC||Need Help??|
Is my understanding right? Anything else about lists that I should know about?It seems to me that there's a major point that you are missing.
There is a difference between an expression and its value. An expression is a sequence of characters in the source code. When the program is run, Perl evaluates the expression, and the result is a value. A value is not part of the program source code; it only exists inside the computer's memory at run time. As a result, it's hard to talk about value. We say things like this:
"The value of the expression (localtime) is the list (36,38,2,2,3,69,3,91,0)"But this is not really correct, because (36,38,2,2,3,69,3,91,0) is not a list. It is an expression whose value happens to be a list. What we really mean here is that the value of the expression (localtime) is the same as the value of the expression (36,38,2,2,3,69,3,91,0).
We like to say that the expression (36,38,2,2,3,69,3,91,0) is a list expression, because it has a certain simple form, and its value is a list.
Lots of people are confused about this, because it is rarely explained clearly, and because most people do not use the terminology consistently. That is why you see beginners asking questions like this:
My program reads in a line from a file, adds 1, and prints it out. The line is: 037. The manual says that Perl considers numbers that begin with 0 to be octal constants. Why did my program print out 38 instead of 040?The answer is that expressions that contain constants beginning with 0 represent octal constants. But there is no such thing as an octal value. Values aren't octal or decimal or binary; they're hidden inside the computer, and it is None of Your Business how they are represented. In the beginner's example, Perl is converting a string value to a numeric value, and to do that it always interprets the string value as a decimal numeral.
Now, the thing I think you may have missed about context is that it applies to expressions, and never to values. Every time you say "the list on the right-hand side" you are making a mistake. In scalar context, there is no list.
@a is an array expression. In a list context, its value is the list of elements from the array. In scalar context, its value is the length of the array.
(1,2,3) is not a list. It is a comma expression. In list context, its value is a list of the values of the items separated by the commas. In scalar context, its value is the value of the last item.
@a[0..2] is not a list. It is not "a.k.a. a list". It is an array slice expression. In list context, its value is a list of the array elements you selected. In scalar context, its value is the value of the last array element you selected.
localtime() is not a list. It is a localtime expression. In list context, its value is a list of the current seconds, minutes, hours, days, and so on. In scalar context, its value is a string representing the current time.
This is why you have to understand that context applies to expressions, not to values. If you think context applies to values, you get the wrong answer for localtime(). You would say (as you did in (5) above) "Oh, localtime's value is a list of seconds, minutes, hours, and so on, and since it's a list in scalar context, the result is the last element from the list, which is the $dst value." Wrong wrong wrong!
In scalar context, localtime doe not produce a list. No Perl expression produces a list in scalar context.
Your explanation has a bunch of oddities. In (3) you talk about Perl assigning one array to another. But there's only one array there; the ($temp) is not an array.
In the section titled my current understanding:
2.Arrays and lists act the same in list context.This is really missing it, because it's impossible to have a list in scalar context; there is no such thing. You can have a list expression, but that isn't the same as an array slice expression, or a localtime expression, or any other expression whose value might be a list if it were in list context. But the context effect applies to the expression itself, not to its value, because all contextual effects occur at compile time, never at run time, and at compile time there are no values; the values do not appear until run time, after all the contextual effects are resolved.
Perl5-porters got email about a year ago from a guy who was reporting the following bug:
Following is an account of what could be a bug in perl. $ perl -e 'print "count is ", scalar(undef, undef), "\n"' count is Note that count is undefined here, though it should have been 2.This guy had the same idea you did: (undef, undef) is a list of two items, and scalar() should count the items. But scalar does no such thing. It changes the way the way the program is compiled, so that the comma operator returns its second operand, instead of constructing a list value.
Hope this helps.