George Mpouras said:
of course there are workarounds; I just found it strange because there
is no { } closure to localize the var.
Rainer said the goto is not compiled, ok, this explains the behavior,
but it is also strange
The compiler doesn't run the program, hence, it doesn't follow it's
runtime control flow. It basically processes an input file sequentially
from the first line to the last line, similar to a person walking
backwards on a straight path: It can see everything it already
encountered so far but can't look at anything it might encounter during
the course of the next five steps. Another way to describe this would be
that the location on this path were the person/ compiler presently
stands represents 'the present', the set of previously occupied
locations would be 'the past' and anything behind (the person/ compiler
is still looking backwards) was 'the future' and nothing is really known
about that (although an intelligent being could come up with a set of
more or less likely conjectures about it). 'goto' can be used to
introduce arbitrary twists and turns in this otherwise sequential flow of
time (that's what's behind the ominous murmur of
http://www.u.arizona.edu/~rubinson/copyright_violations/Go_To_Considered_Harmful.html
) but only when it is actually executed.
Assuming the following Perl code:
-------
goto omy;
ohyou:
print $MODE, "\n";
exit 0;
ohmy:
$MODE = 5;
goto ohyou;
-------
The 'Perl dissassembler' can be used to display the 'op tree' generated
from this. It is (perl -MO=Concise ...):
i <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 a.pl:1) v:{ ->3
3 <"> goto("omy") v ->4
4 <;> nextstate(ohyou: main 1 a.pl:3) v:{ ->5
8 <@> print vK ->9
5 <0> pushmark s ->6
- <1> ex-rv2sv sK/1 ->7
6 <#> gvsv[*MODE] s ->7
7 <$> const[PV "\n"] s ->8
9 <;> nextstate(main 1 a.pl:5) v:{ ->a
b <1> exit vK/1 ->c
a <$> const[IV 0] s ->b
c <;> nextstate(ohmy: main 1 a.pl:7) v:{ ->d
f <2> sassign vKS/2 ->g
d <$> const[IV 5] s ->e
- <1> ex-rv2sv sKRM*/1 ->f
e <#> gvsv[*MODE] s ->f
g <;> nextstate(main 1 a.pl:9) v:{ ->h
h <"> goto("ohyou") v ->i
The 'gotos' appear in that as 'operator with a string argument', that's
what the compiler makes of them. This code can't really be executed
because of the intentional spelling error in the first line ('omy'
versus 'ohmy') but op-tree generation step is oblivious of (to?) that.
This is also documented behaviour, cf
The declared variable is not introduced (is not visible) until
after the current statement. Thus,
my $x = $x;
can be used to initialize a new $x with the value of the old $x
(perldoc perlsub)