in reply to Re: static-like persistence of my variable due to trailing conditional
in thread static-like persistence of my variable due to trailing conditional

I'm not sure that quite works. In theory, on the first call, my $foo = "blah" should be run, then go out of scope at the end of the function call. So, if the declaration/assignment is not run on the second call, shouldn't $foo ||= "FOO" give us an error?


_______________
D a m n D i r t y A p e
Home Node | Email

Replies are listed 'Best First'.
Re^3: static-like persistence of my variable due to trailing conditional
by Aristotle (Chancellor) on Jun 29, 2002 at 22:43 UTC
    I vaguely recall reading something about the duality of run-/compilation timeness of my causing this. Unless I'm off by several orbits, the cause was that the scope is determined at compilation time, but the actual scalar is allocated at runtime, and is the same thing as causes $bar to persist in things like
    sub foo { my $bar = 0; sub baz { print $bar++; } }
    (You know the drill - Variable "$bar" will not stay shared.)

    Makeshifts last the longest.

Re: Re: Re: static-like persistence of my variable due to trailing conditional
by mschout (Initiate) on Jun 30, 2002 at 04:54 UTC
    The reason we cant give an error is because my $foo = "blah" only gets executed if $var is true. However, we dont actually know if $var is true or not until runtime.

    So when you call mycode() with no arguments then my $foo = 'blah' is not executed at all. Instead, simply $foo = 'FOO' gets executed, setting $main::foo (you can verify this by printing out $main::foo after you call mycode() with no arguments).

    use strict is only supposed to catch compile-time errors (according to its documentation). It should not blow up at runtime.

    To do what you expect here you could do something like:

    
        my $foo = defined $var ? 'blah' : 'FOO';
    or even:
    
        my $foo;
        if ($var) {
            $foo = 'blah';
        }
        else {
            $foo = 'FOO';
        }
    
      my $foo = 'blah' is not executed at all. Instead, simply $foo = 'FOO' gets executed, setting $main::foo (you can verify this by printing out $main::foo after you call mycode() with no arguments).

      Wrong. Actually, the fact that $foo is scoped lexically must be known at compile time - think about it, how else would strict work? After the compiler sees a my, it generates ops referring to lexicals rather than globals for the variables. However, allocation of these lexicals happens at runtime. By adding an if, you prevent the allocation at runtime, but you do not prevent the lexical scoping that happens at compile time.

      The effect is that subsequent invocations of the routine refer to a lexically scoped scalar that was allocated in a previous invocation - the same way as closures do.

      Makeshifts last the longest.

      I concur, except for this part:
      So when you call mycode() with no arguments then my $foo = 'blah' is not executed at all. Instead, simply $foo = 'FOO' gets executed, setting $main::foo (you can verify this by printing out $main::foo after you call mycode() with no arguments).
      I had a line in my original code that dumped the symbol table:

      print Dumper(\%main::);

      But threw this out because I am never able to see $foo in the symbol table for the main package. Are you?

      ---
      "A Jedi uses the Force for knowledge and defense, never for attack."