Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Re^3: Use of "my" after Perl v5.14

by tobyink (Abbot)
on Sep 20, 2012 at 23:20 UTC ( #994779=note: print w/replies, xml ) Need Help??

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

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'

Replies are listed 'Best First'.
Re^4: Use of "my" after Perl v5.14
by Rohit Jain (Sexton) on Sep 20, 2012 at 23:27 UTC

    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'
        use v5.14; { my $count = 1; sub counter { say $count++; } } counter(); counter(); counter(); counter();

        Unfortunately, this approach hides a subtle pitfall — well, subtle enough, at any rate, to catch me more than once. The problem is here illustrated:

        >perl -wMstrict -le "use v5.14; ;; counter(); counter(); ;; { my $count = 42; ;; sub counter { say $count++; } } ;; counter(); counter(); " 0 1 42 43

        There is a critical dependence upon order of execution. The  $count lexical variable is created at compile time, so the  counter() function has no problem accessing it; the code runs with warnings and strictures fully enabled. The variable is not initialized within its closure until some moment during run time; this moment may precede or follow any invocation of the function that quite happily accesses the variable. KaBoom!

        It's pretty easy to avoid this problem: perhaps the easiest way is to just use a state variable! But the first step toward avoidance is awareness.

        I have this code: -

        #!/perl/bin use v5.14; sub total { local $::@numList = @_; # This line is giving Compiler error.. my $sum = 0; # ForEach is not working in this case.. Even when I use my @nu +mList in declaration.. foreach (@numList) { say "list ", @numList; # Printing 3 (if 1, 2, 3) is input.. say "sum is : $sum"; $sum += $_; } $sum; } say "Enter a list of number to calculate sum :"; my $total = total(chomp(my @numList = <STDIN>)); say "Total : $total";
        I can't understand what can be the problem with the code.. I am trying to find the total of some integer from user input..

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://994779]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (8)
As of 2018-05-24 20:03 GMT
Find Nodes?
    Voting Booth?