> Out of morbid curiosity (since I'm working on documentation), given the
> program that the following program generates:
>
> #!/your/path/to/perl -w # perl 5.6.1
> my @l = ('a' .. 'g');
> my $my = 0;
>
> for my $v (@l) {
> my @a = map { "\$$v .= '$_'" } @l;
> $a[$my++] = "my $a[$my]";
> print shift @a, ";\n{\n ",
> join (", ", @a[@a/2 .. $#a]), " if ",
> join (", ", @a[0 .. @a/2-1]), ";\n";
> print <<"EOF";
> print "$v: \$$v\\n";
> }
> print "$v: \$$v\\n";
>
> EOF
> }
> __END__
>
> I'm found tests B, C, and D a little surprising. I expected 'befg/acd',
> 'cefg/abd', and 'defg/abc' (lexical/global answers, respectively).
>
> Although I now understand what it does, I'm still fuzzy on the why and how.
> Can someone in the know give a clear enough explanation that I can document?
Its due to the fact that my variables dont come into scope until the
end of the expression in which they are defined. eg
my $a = 8;
{
my $a = $a+1;
print $a; # prints '9', not 1
}
In the expression "my $a = ...", the "..." is evaluated as if $a has not yet
been defined (in perl5 internals terminology, it hasn't yet been introduced).
So "my $a = $a+1" is parsed as "my $inner_a = $outer_a + 1".
A similar thing happens with:
my $a = 10;
foreach my $a ($a..$a+5) {
print "$a\n"; # prints 10..15
}
the new $a doesnt come into scope until the start of the { } block.
In your code,
$b .= 'a';
{
$b .= 'e', $b .= 'f', $b .= 'g' if my $b .= 'b', $b .= 'c', $b .= 'd';
print "b: $b\n";
}
print "b: $b\n";
"A if B" is syntactically equivalent to "(B) && (A)" (in fact that's how
the perl 5 parser handles it), so you have
(my $b .= 'b', $b .= 'c', $b .= 'd') && ($b .= 'e', $b .= 'f', $b .= 'g')
and the lexical $b doesnt come into scope until the end of that expression.
So the expression is really
(my $inner_b .= 'b', $outer_b .= 'c', $outer_b .= 'd')
&& ($outer_b .= 'e', $outer_b .= 'f', $outer_b .= 'g')
Dave "who by coincidence spent the last couple of weekends staring at the
pad code in op.c etc trying to make some sort of sense out of it (and
mostly failing)" M.