[Wellington-pm] A question about scopes
Jacinta Richardson
jarich at perltraining.com.au
Sun Mar 26 04:34:06 PST 2006
Cliff Pratt wrote:
-------------------------------------
> use MyGame ;
> .
> my @grid ;
> .
> .
> # Recent change - I now pass the grid to the packaged sub and
> # return it when modified.
> @grid = MyGame::sub1(@grid) ;
-------------------------------------
> package MyGame;
>
> # Recent change - This now outside any sub.
> my @grid ;
>
> sub sub1 {
> # @grid, but which one?
> @grid = @_ ;
> .
> return @grid ;
> }
-------------------------------------
In this particular case, I'd rewrite your code as follows:
-------------------------------------
#!/usr/bin/perl -w
# main.pl
use strict;
...
my @grid = MyGame::sub1(@grid) ;
...
-------------------------------------
package MyGame;
sub sub1 {
my @grid = @_; # See below
...
return @grid;
}
-------------------------------------
In this code, @grid is lexically scoped to sub1. This means that it only exists
inside sub1. You could change its name to be @game_grid throughout that
subroutine and the outside code should not be affected. Now having said that,
if you need sub1 to set up the grid and then have that set-up grid be available
to other functions in the package, then I'd recommend considering closures:
-------------------------------------
package MyGame;
{
my @game_grid;
sub sub1 {
my @grid = @_;
...
@game_grid = @grid; # explicit copy
return @grid;
}
sub sub2_which_uses_game_grid {
...
... @game_grid ...
...
}
}
sub sub3_which_doesnt_use_game_grid {
...
}
-------------------------------------
A closure works by limiting the scope of a lexical variable. In my example
above, only sub1 and sub2_which_uses_game_grid can see the @game_grid variable.
This makes the variable more "private" and hopefully reduces the chance that it
gets changed unexpectedly.
You'll notice that I still use lexical variables inside sub1 and then explicitly
copy into @game_grid. This helps later programmers find where @game_grid gets
set, and prevents them from either cutting and pasting your code and thus
accidently over-writing the grid variable, or alternately assuming that you've
made an error by not using "my" and breaking your code that way.
I hope this helps.
Jacinta
--
("`-''-/").___..--''"`-._ | Jacinta Richardson |
`6_ 6 ) `-. ( ).`-.__.`) | Perl Training Australia |
(_Y_.)' ._ ) `._ `. ``-..-' | +61 3 9354 6001 |
_..`--'_..-_/ /--'_.' ,' | contact at perltraining.com.au |
(il),-'' (li),' ((!.-' | www.perltraining.com.au |
More information about the Wellington-pm
mailing list