http://www.perlmonks.org?node_id=994774


in reply to Re: Use of "my" after Perl v5.14
in thread Use of "my" after Perl v5.14

Thanks tobyink for such a elaborated and nice explanation..

Replies are listed 'Best First'.
Re^3: Use of "my" after Perl v5.14
by tobyink (Canon) on Sep 20, 2012 at 23:20 UTC

    I suppose it's also worth mentioning that my and our have two other friends: local and state.

    local sets a new, temporary value for a package variable, which expires at the end of the current scope, with the variable's original value being restored.

    In this example, bar() sets $::hello temporarily to "Goodbye" and this new value is visible to foo(), but after bar() has finished running, the original value of "Hello" is restored again.

    use v5.14; sub foo { say $::hello; } sub bar { local $::hello = "Goodbye"; foo(); } $::hello = "Hello"; bar(); say $::hello;

    And state can be used to create a variable which keeps its state, not being re-initialised.

    use v5.14; sub counter { state $count = 1; say $count++; } counter(); counter(); counter(); counter();
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      Then I suspect, local works just like control variable in foreach loop, where I read that, if the control variable is already declared before the loop, then its value will be restored after the foreach loop ends.

      E.g: -

      my $packageVar = 5; foreach $packageVar (@someArr) { # Some code } print $packageVar; # Will print 5;

      *EDIT: - Didn't saw this difference.. The "local" state of variable is visible accross multiple subroutines (in fact at all places in that file I guess) untill we get out of scope of that subroutine.. That is not the case with foreach loop..

        local can generally be implemented manually. The following two are pretty much exactly equivalent.

        ## Example 1 our $x = "Hello"; sub f { local $x = "Goodbye"; ...; } f(); ## Example 2 our $x = "Hello"; sub f { my $original = $x; $x = "Goodbye"; ...; $x = $original; # restore } f();

        local just means that you don't have to remember to manually restore the original value, which can be especially tricky if your sub has several different exit routes (e.g. different return statements in if blocks). Given that local is so much easier than the manual way, there's little reason to go down the manual route. However situations where you need to do this kind of thing are usually pretty rare, and often confined to Perl's built-in variables like $_ and $/.

        state is also not especially difficult to handle manually. The following is a reimplementation of my previous "counter" example:

        use v5.14; { my $count = 1; sub counter { say $count++; } } counter(); counter(); counter(); counter();

        Unlike local there is a valid reason to avoid state. It's a relatively new feature, so if you use it your code will not run on Perl versions prior to 5.10.

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'