From: Dan Boger <[EMAIL PROTECTED]>
Date: Wed, 10 Jan 2007 14:06:04 -0500
On Wed, Jan 10, 2007 at 01:14:43PM -0500, Uri Guttman wrote:
> >>>>> "DB" == Dan Boger <[EMAIL PROTECTED]> writes:
>
> DB> @headers = ("header 1","header 2","header 3");
> DB> @body = ("body A","body B","body C");
> DB> $h = 4;
> DB> foreach (@headers,"",@body) {
>
> the list of aliases is created there. it can't be changed by clearing
> @body. the aliases refer to the elements passed to foreach and not
> where they came from. it is like keeping a ref to a lexical var after
> it leaves scope. the var is still around due to ref counting and you
> can access it via the ref but the original access is lost.
Yup, that's what I thought.
No, not quite . . . though it does show that array assignment creates a
new array object and stores the ref in @body, rather than side-effecting
the array object to which @body points.
. . .
Great. But according to what you say here (and what I thought would
happen), the output would be . . .
Remember how Perl [1] avoids generating huge lists for large range
iterations? E.g.
for my $i (1..10000000) { ... }
is done in constant space. You just demonstrated that array iteration
is done in a similar way; the array enumeration is interleaved with
execution of the body, instead of enumerating all elements beforehand.
This turns out to be true even if given an arrayref, e.g.
for my $i (@$stuff) { ... }
Therefore, foreach must use a list of aliases *to arrays*, not aliases
to array elements. This is a good hack, but it surprises me, too.
FWIW, the comma (list) operator appears to force enumeration, e.g.
for my $item (@$stuff, () x 0) { ... }
Neat, eh? Takes me back to Lisp before Common Lisp . . . too bad the
Perl idiom for "empty list" is not as concise.
-- Bob Rogers
http://rgrjr.dyndns.org/
[1] Since 5.6.1?
_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm