Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Re^4: Lexical closures

by chromatic (Archbishop)
on Oct 25, 2008 at 18:40 UTC ( #719531=note: print w/replies, xml ) Need Help??

in reply to Re^3: Lexical closures
in thread Lexical closures

It's not a bug; it was a deliberate design decision in (I believe) 5.004. Besides, you don't have to put my there. The aliasing works with global variables too:

use 5.010; package Foo; use vars '$i'; use strict; use warnings; sub bar { for $i (1 .. 10) { main::baz( $i ); } } package main; use strict; use warnings; use Test::More tests => 12; $Foo::i = 100; sub baz { my $expect = shift; is( $Foo::i, $expect ); } baz(100); Foo::bar(); baz(100);

Replies are listed 'Best First'.
Re^5: Lexical closures
by backstab (Novice) on Oct 25, 2008 at 21:37 UTC
    I think we can also show how the aliased variable can be global with the following,
    use vars '$i'; $i = 123; sub foo { my $arg = shift; print "$arg, $i\n"; } foreach $i (0..2) { foo($i); } foo('x'); # obviously alias works only within the loop # Prints, # 0,0 # 1,1 # 2,2 # x,123
    If so, I have a question related to my scope. Within the previous example let's declared $i with my instead.
    my $i; $i = 123; sub foo { my $arg = shift; print "$arg, $i\n"; } foreach $i (0..2) { foo($i); } foo('x'); # Prints, # 0,123 # 1,123 # 2,123 # x,123

    At this point I'm confused in fact. Should not we get the same result? Does not my scope to nested blocks as well?

    It looks like aliasing does not affect my'd variable despite to be within the same scope or nested scope. The previous result is what I have expected using my on the foreach itself.

      In the second snippet, foo() captures $i since $i is a lexical. That means the $i in foo() will always refer to the specific SV associated with $i when foo was compiled. When the loop aliases $i to a different SV, it doesn't affect foo.

      use Devel::Peek; my $i; # Lexical variable sub foo { Dump($i); } Dump($i); # SV ... at 0x226048 \ for $i ( 1 ) { # > same foo(); # SV ... at 0x226048 / Dump($i); # SV ... at 0x226d8c }

      In the first snippet, there is no closure since $i is not a lexical. That means the foo() will always grab the current value of $main::i.

      use Devel::Peek; our $i; # Package variable sub foo { Dump($i); } Dump($i); # SV ... at 0x226d94 for $i ( 1 ) { foo(); # SV ... at 0x226d7c \ same Dump($i); # SV ... at 0x226d7c / }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://719531]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2019-07-22 10:18 GMT
Find Nodes?
    Voting Booth?
    If you were the first to set foot on the Moon, what would be your epigram?

    Results (14 votes). Check out past polls.