[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