[Wellington-pm] A question about scopes

Cliff Pratt enkidu at cliffp.com
Tue Mar 28 13:05:10 PST 2006


Jacinta Richardson wrote:
> 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
> 
Yes, it does. Thanks Jacinta. I've yet to get my mind around closures, 
though, so I'll steer clear of them for now. I've actually solved most 
of the problems with my program one way or another, with the help of 
yours and other people's hint. It's much appreciated!

Cheers,

Cliff

-- 

http://barzoomian.blogspot.com


More information about the Wellington-pm mailing list