Marcus Gaius Publius Dominus on Sat, 28 Jun 2003 15:29:21 -0400 |
Jeff Abrahamson <jeff@purple.com>: > But isn't > > $foo =~ s/.html$//; > > scalar context? Scalar or list context is not an intrinsic property of an expression. It is a property not of the expression itself, but of the, er, the context in which it appears. Imagine if someone were to ask you "Isn't 'Do not touch that' in a satiric context?" Then you would say "How should I know? I would have to see the context." Any expression can be in list or scalar context; it depends on the context, not on the expression. In $s = EXPRESSION; the expression is in scalar context; in @a = EXPRESSION; it is in list context. Here the statement under consideration is: > > @indices = map { $_ =~ s/.html$// } @indices; The parse tree here is = @indices map =~ $_ s/.html$// @indices The contexts for each operator are: = void @indices (no context) map list =~ s/.html$// list $_ scalar @indices list The = is in void context because the value of the entire statement will be thrown away. If we had if (@indices = map { $_ =~ s/.html$// } @indices) { ... } then the = would be in scalar context. @indices on the left is an lvalue--it is the target of an assignment. Such expressions don't have a context, because context is all about the value that an expression will produce when it is evaluated, and expressions to the left of an assignment operator are not evaluated. 'map' is in list context, because it is on the right-hand side of an assignment to an array expression. =~ is a little funny, because the value it produces depends on whether it is binding to a tr///, a s///, or a m// expression. The simplest way to think about it is that the =~ and the s/// are a single expression. They are in list context, because the first argument to 'map' is always in list context. The essence of your question, then is "what value does '=~ s///' produce in list context?" I'll return to this below. $_ is in scalar context because it is bound to =~ s///, and an expression bound to =~ s/// is always in scalar context. Finally, @indices on the right is in list context, because the additional arguments of 'map' are always in list context. Now what about =~ s///? In scalar context, =~ s/// returns the number of successfully performed substitutions, if there were any, and otherwise it produces the empty string "", which happens to be false. In list context, =~ s/// produces a list that always has exactly one value. That value is the number of successfuly performed substitutions, if there were any, and an empty string if not. That is, it's a list with exactly the same value that it would have produced in scalar context. So the outcome of your 'map' expression is to concatenate these lists together. You get a list with one numeric element when a substitution was done, and a list with one empty string element when no substitution was done. The context rules can be subtle. Consider the common locution while (($k, $v) = each %hash) { ... } Here the 'each' operator is in list context, but the '=' operator is in scalar context. People often find this sort of thing confusing. - **Majordomo list services provided by PANIX <URL:http://www.panix.com>** **To Unsubscribe, send "unsubscribe phl" to majordomo@lists.pm.org**
|
|