[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

[MacPerl][off topic] local & my (was Re:Any way to Tee...)



This is a purely PERL related article, addressing the recent discussion on
this list between Chris Nandor and Mark Manning over the meaning and
function of "local()". I voice my own opinion on the subject, then provide
a war story and two code samples which I used to clarify the issue in my
own mind.

Although you decided to ignore the offtopic warning in the subject and your
mail reader has by now already formatted the article, you can chose not to
waste more time by deleting this message now. My apologies for cluttering
your mailbox (and this mailing list) with this off-topic post, but I
figured someone out there might be as confused about local() as I was, and
this might help.

<----- off-topic post starts now ----->

At 07:49 +1100 on 14/2/98, Chris Nandor wrote:
>At 15.24 1998.02.13, Mark Manning/Muniz Eng. wrote:

>You are using bad terminology.  A global is a global is a global.  Putting
>local() on it does not change that.  All it does is temporarily change the
>value of that global variable for the duration of the dynamic scope of the
>enclosing block.

Just a suggestion, guys ... anytime  you start arguing about the meaning of
the terms you use (eg: local()/my()/local/global,
\r/\n/carriage-return/line-feed/new line), try attaching the *meaning* of
what you're saying to dummy words like "camel".

For example, local() redefines a variable to be of camel scope. Now define
"camel scope" as being "accessible to this block and other blocks called by
it". Using words like "local", "global" and "dynamic" will bind your term
to whatever the reader's own definition of "local" and "global" is (or what
\r and \n *should* be).

<----- start war story ----->
I started using this approach one time when I was having an argument with a
friend about some code to handle a heap/stack. I kept talking about "bottom
of heap" where he kept talking about "top of stack"... they were actually
the same thing. I built heaps down from the top of memory, so the bottom is
where I add things on and take things off, while his model of memory was
"upside down" to mine - he built his stack by putting things on the top. My
heap elements were (conceptually) helium filled balloons in a tall room,
while his were (conceptually) lead weights in a deep well. My heap and his
stack were effectively the same thing, but we argued for hours about simple
things like what was meant by "TopPtr" and "BotPtr".
<----- end war story ----->

To my understanding, a local() variable is of local scope, meaning
everything inside/below the current "block". In contrast, consider that
my() is of lexical scope only. Witness the following code:

<----- START CODE SAMPLE 1 ----->
#!perl

sub DefineLocal {
	local $my_local_var = 5;
	print "Defined my local variable as $my_local_var\n";
}

if( defined( $my_local_var ) ) {
	print "My local variable is defined as $my_local_var\n";
}
else {
	print "My local variable is not defined yet\n";
};

DefineLocal();

if( defined( $my_local_var ) ) {
	print "My local variable is defined as $my_local_var\n";
}
else {
	print "My local variable is not defined yet\n";
};
<----- END CODE SAMPLE 1 ----->

At no point is $my_local_var accessible by the main program (which it would
be if local() == "global scope").

According to the documentation, the *semantics* of local is that "local
modifies the listed variables to be local to the enclosing block", while my
understanding of the *technique* for performing this feat is as described
by Mark - the "outside" value of the variable is pushed on to a stack for
the remainder of this block (and its enclosures), then popped off the stack
on the way back "outside". Once again, witness the following code:

<----- START CODE SAMPLE 2 ----->
#!perl
local $my_local_var = "Main Block";

sub DisplayVar {
	return $my_local_var;
};

sub RedefineUsingLocal {
	print "On entry to RedefineUsingLocal: ", DisplayVar(), "\n";
	$my_local_var = "Main Block After Local";
	local $my_local_var = "Local Block";
	print "As we exit RedefineUsingLocal: ", DisplayVar(), "\n";
};

sub RedefineUsingMy {
	print "On entry to RedefineUsingMy: ", DisplayVar(), "\n";
	$my_local_var = "Main Block After My";
	my $my_local_var = "My Block";
	print "As we exit RedefineUsingMy: ", DisplayVar(), "\n";
};

print "\n-----\nAt the start of main block: ", DisplayVar(), "\n";
RedefineUsingLocal();
print "After calling local redefinition: ", DisplayVar(), "\n";
RedefineUsingMy();
print "After calling my redefinition: ", DisplayVar(), "\n";
print "\n-----\n";
<----- END CODE SAMPLE 2 ----->

Thanks for the argument, Chris and Mark... it was only through your
conflagration that I found the motivation to figure out the difference in
my() and local() for myself!

Another way of thinking of local() is that it creates a "overrides" a
previous declaration of a "global" variable. my() only provides an override
for the current block, and nowhere else either "inside" or "outside" - thus
the redefinition using "my $my_local_var" is never seen anywhere.

I remember there being an article somewhere about the differences between
"local" and "my"... but I've lost track of it. If anyone knows where it is,
can you let me know?

Regards,
Alex Satrapa

Windows 95: n. 32 bit extensions and a graphical shell for a 16 bit patch
to an 8 bit operating system originally coded for a 4 bit microprocessor,
written by a 2 bit company that can't stand 1 bit of competition.
                   http://ucnet.canberra.edu.au/~packrat/windows_sig.html



***** Want to unsubscribe from this list?
***** Send mail with body "unsubscribe" to mac-perl-request@iis.ee.ethz.ch