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

Re: [MacPerl] defining variables if not already defined



> I'm confused by your confusion :-) Study Perl precedence and control
> flow. The statement
> my $test = 1 if 0
> 
> is equivalent, control-flow-wise, to:
> 
> if 0 {
> my $test = 1
> }
> 
> In Bart's example, this condition is never reached*. The third time
> foo is called, $test still has the value from the second time. If you
> ran this code with -w, you'd get a complaint about $test being
> unititialized.

I think the confusion is rooted in the difference between run-time and
compile-time. During run-time, the "my $test = 1" function is never actually
executed. However, during compile-time, Perl allocates scope and space for
the $test variable regardless of run-time conditions because (AFAIK) it does
not determine whether the function would ever be called during run-time. And
so, because $test is scoped lexically, it does not exist outside of the
subroutine that defines it. Simply print the value of $test anywhere outside
of the subroutine to verify so. But there is a run-time effect of the my()
function that Perl expects would be executed, but never does, and it creates
the side effect of a variable with a value accessible only from within the
subroutine but persistent across subroutine calls. You can easily test this
yourself:

#!perl

concat( "foo" );
concat( "bar" );
concat( "?");

print "\nGlobal value of \$foo: $foo\n";

sub concat {
  my $bar;
  my $foo if 0;        # always false--never executed?
  $foo .= $_[0];
  $bar .= $_[0];

  print "\$foo = $foo\n\$bar = $bar\n";
}

__END__

I hope this is a clearer explanation.

-K

-- 
"... and here comes the ice-pick, in the forehead!"
    - Frank Zappa, _Fembot in a Wet T-Shirt_

> From: Bruce Van Allen <bva@cruzio.com>
> Date: Fri, 28 Jul 2000 18:24:39 -0700
> To: Stewart Leicester <StewartL@JenSoft.com>, MacPerl mailing list
> <macperl@macperl.org>
> Subject: Re: [MacPerl] defining variables if not already defined
> 
> At 2:24 PM 7/28/00, Stewart Leicester wrote:
>> Now I'm confused. I thought that "my $test = 1 if 0;" would
>> lexically scope $test to foo alone but it appears that only happens
>> if "my $test = 1" is executed.
>> 
>> What am I missing?
>> 
>> Stewart
> 
> At 6:02 PM 7/28/00, Keary Suska wrote:
>> This is a rather bizarre side effect, but I think what Bart is trying to
>> [snip]
>> "$test" as a lexically scoped variable, and ends up creating a weird ad-hoc
>> static scope (vis a vis C). An interesting exploit (if you want a static
> 
> I'm confused by your confusion :-) Study Perl precedence and control
> flow. The statement
> my $test = 1 if 0
> 
> is equivalent, control-flow-wise, to:
> 
> if 0 {
> my $test = 1
> }
> 
> In Bart's example, this condition is never reached*. The third time
> foo is called, $test still has the value from the second time. If you
> ran this code with -w, you'd get a complaint about $test being
> unititialized.
> 
> *By the way, what's being tested for a zero (or false, perhaps) value
> here, anyway? @_ in a sub isn't the same as implicit $_ in a foreach
> loop.
> 
>> 
>>> On Fri, 28 Jul 00 12:28:59 +0900, Joel Rees wrote:
>>> 
>>>> Does my() always operate at compile time? Does that mean that my hopes
>>>> for easy run-time allocation must be dashed?
>>> 
> 
>> Bart Lateur replied:
>>> my() has both a compile time, and a runtime effect.
>>> 
>>> At compile time, it takes care of scoping issues. So, you cannot
>>> possibly use a variable in fixed code, that is allocated at runtime in
>>> eval STRING. The mere fact that a variable is accessed, makes sure that
>>> it is allocated, so these would refer to different variables.
>>> 
>>> At runtime, it takes care of storage allocation.
>>> 
>>> An example of the confusing side effects can be seen in:
>>> 
>>> $\ = "\n";
>>> print foo(10);
>>> print foo(20);
>>> print foo(10);
>>> 
>>> sub foo {
>>> my ($comp) = @_;
>>> my $test = 1 if 0;
>>> $test = 2 if $comp == 20;
>>> $test || 3;
>>> }
>>> 
>>> This prints:
>>> 
>>> 3
>>> 2
>>> 2
>>> 
>>> So, don't do this.
>>> 
>>> In summary: you needn't worry about compile time allocation. You need
>>> the declaration at compile time, to take proper care of scoping. But
> [snip]
>>> Bart.
> 
> 
> 1;
> -- 
> 
> - Bruce
> 
> __Bruce_Van_Allen___bva@cruzio.com__Santa_Cruz_CA__
> 
> # ===== Want to unsubscribe from this list?
> # ===== Send mail with body "unsubscribe" to macperl-request@macperl.org
> 


# ===== Want to unsubscribe from this list?
# ===== Send mail with body "unsubscribe" to macperl-request@macperl.org