goto

G

George Mpouras

# why it complaints ?
use strict;
use warnings;
goto Initialize_variables;
main_loop:
print $MODE;
goto end;
Initialize_variables:
my $MODE = "hello world\n";
goto main_loop;
end:
 
R

Rainer Weikusat

George Mpouras said:
# why it complaints ?
use strict;
use warnings;
goto Initialize_variables;
main_loop:
print $MODE;
goto end;
Initialize_variables:
my $MODE = "hello world\n";
goto main_loop;
end:

-----
use Devel::peek;

goto Initialize_variables;
main_loop:
print $MODE;
Dump($MODE);
goto end;
Initialize_variables:
my $MODE = "hello world\n";
Dump($MODE);
goto main_loop;
end:
-----

The compiler doesn't execute goto-statements, hence, by the time the

print $MODE;

is compiled, it refers to an undeclared package variable named $MODE.
 
$

$Bill

-----
use Devel::peek;

goto Initialize_variables;
main_loop:
print $MODE;
Dump($MODE);
goto end;
Initialize_variables:
my $MODE = "hello world\n";
Dump($MODE);
goto main_loop;
end:
-----

The compiler doesn't execute goto-statements, hence, by the time the

print $MODE;

is compiled, it refers to an undeclared package variable named $MODE.

In other words, 'declare' $MODE prior to it's first use in file:

use strict;
use warnings;
my $MODE;
goto Initialize_variables;
main_loop:
print $MODE;
goto end;
Initialize_variables:
$MODE = "hello world\n";
goto main_loop;
end:

__END__
 
C

Charles DeRykus

# why it complaints ?
use strict;
use warnings;
goto Initialize_variables;
main_loop:
print $MODE;
goto end;
Initialize_variables:
my $MODE = "hello world\n";
goto main_loop;
end:

You could globalize $MODE as a workkaround:

use vars qw/$MODE/;
...
#my $MODE = "hello,world";
$MODE = "hello world";

or, just change the lexical scope:

my $MODE;
goto Initialize_variables;
...
Initialize_variables:
#my $MODE = "hello,world";
$MODE = "hello world\n";
 
G

George Mpouras

You could globalize $MODE as a workkaround:

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
 
C

C.DeRykus

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, the error is due to 'strict'. I'm not sure how closure
and localizing create any confusion.
but it is also strange

It'd be even stranger if goto had some kind of compile-time
behavior that could alter the semantics of lexical scope.
 
R

Rainer Weikusat

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)
 
H

Huge

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.

Hence multi-pass compilers ...
 
P

Peter J. Holzer

of course there are workarounds; I just found it strange because there
is no { } closure to localize the var.

A lexical variable is visible from the point where it is declared until
the end of the enclosing block. Since there are no {} in your code the
"enclosing block is your whole file.

So in

1| use strict;
2| use warnings;
3| goto Initialize_variables;
4| main_loop:
5| print $MODE;
6| goto end;
7| Initialize_variables:
8| my $MODE = "hello world\n";
9| goto main_loop;
10| end:

the variable $MODE is visible from the end of line 8 to line 10.

If you had written something like

1| use strict;
2| say "$MODE not visible";
3| {
4| say "$MODE still not visible";
5| my $MODE = "foo";
6| say "$MODE visible here";
7| }
8| say "$MODE not visible again";

$MODE would be visible from the end of line 5 to line 7.

hp

PS: There is a reason why variables declared with my() are called
"lexical" variables.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top