in reply to Re^4: Is use strict always appropriate?
in thread Please help me print this hash.
A couple of points.
"unless the other subroutine is defined within the sub containing the my scoped valiable" - don't define named subroutines within named subroutines! Ever!
sub outer { ... sub inner { } ... }
This is never a good idea. First, the inner() subroutine will not be local to the outer() one, it will still be globally accessible. Second, if you use a lexical variable (variable declared with my) defined in outer() within inner() you will get the "Variable will not stay shared" warning and strange things will happed in runtime. The thing is that each invocation of the outer() creates a new instance of the lexical variable, but the inner() may be called directly or recursively or ... so there is no good way to tie the $x in inner() to a specific instance in outer().
If you want a subroutine to change a lexical declared in another, pass a reference or make use the fact that $_[...] is an alias to the parameter. If you want to have a shared state for two subroutines, use this:
{ my $hidden_data; sub one { ... access the $hidden_data; ... } sub two { ... access the $hidden_data; ... } }
It's legal though to use a lexical variable in an unnamed subroutine defined within a subroutine like this:
sub outer { my $lexical = ...; ... my $inner = sub { ...; access $lexical; ... }; ... $inner->(...); #or even return $inner; }
In this case the $inner subroutine is lexical and defined in the same or smaller scope as the $lexical so there is no confusion regarding which instance of $lexical should it be accessing. And if you return or store the $inner, the value of $lexical will be preserved and will not be garbage collected until all references to the unnamed subroutine are cleared.
local is in no way similar. First and foremost, local doesn't declare a new variable. It takes a "slot" (it may be global variable or array or hash element, but not a lexical variable), stacks its value away and undefines the slot. Then when the execution leaves the enclosing block, the old value is reassigned to the slot.
Apart from other things this means that
my $hash{key} = ...; # is illegal local $hash{$key} = ...; # is legal #on the other hand my $x = 1; { my $x = 2; # is legal, a new variable was created, outer $x is not v +isible } #while my $x = 1; { local $x = 2; # is illegal. Can't localize a lexical variable
"If the variable is defined in the same block as the subroutines then my and local are effectively the same" - INCORRECT! Try this:
versusour $variable = 15; { local $variable = 33; sub one { print "in one(): \$variable = $variable\n"; } sub two { print "in two(): \$variable = $variable\n"; } } one(); two(); $variable = 99; one(); two();
our $variable = 15; { my $variable = 33; sub one { print "in one(): \$variable = $variable\n"; } sub two { print "in two(): \$variable = $variable\n"; } } one(); two(); $variable = 99; one(); two();
In the first example the $variable (the only $variable in the whole script! A global variable!) is only ever set to 33 while defining the two subroutines, but not when you call them.
In the second there are two variables called $variable. A global one assigned on line 1 and 16 and a lexical one declared at line 4 and accessed at lines 6 and 9. The lexical variable is visible only within the enclosing block but stays alive for the whole runtime of the script, the RUNTIME effects of local only lasted for a tiny moment before any of the subroutines were called.
Read also Coping with Scoping
Jenda
Enoch was right!
Enjoy the last years of Rome.
|
|---|