Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

declare my variable in loop

by gauss76 (Acolyte)
on Aug 08, 2017 at 08:11 UTC ( #1196954=perlquestion: print w/replies, xml ) Need Help??
gauss76 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Perl Monks,

I am fairly new to Perl and have recently produced the following piece of code. I have tested it extensively and it returns the desired results. However I just wondered if someone with more experience of Perl could advice me on its usability.

Basically, I have declared an array variable with the 'my' keyword inside a for loop. I then use the address of this declared array variable in another array variable that has been declared before the aforementioned for loop. The basic code structure looks like this:

my @Array_of_ALL_Vals; for my $iloop (0 .. 10){ my @Array_Vals; Code in here to populate @Array_of_Vals } push @Array_of_ALL_Vals,\@Array_Vals;

The @Array_Vals variable is, in general, a different size each time. In addition the array @Array_Vals defined inside the loop is not used anywhere else in the code and is local to the for loop.

My concern is with the declaration of the array within the for loop. Even though the name of the variable is the same each time I assume for each loop it gets assigned to a different memory address thus the values in the @Array_of_ALL_Vals array do not get overwritten?

I thought it would be better to add an incrementer to the array name inside the for loop so the name would be different each time (@Array_Vals1,@Array_Vals2,...). However after doing some searches I found that would not be a good idea (variable name containing variable)

Many thanks for any comments


Replies are listed 'Best First'.
Re: declare my variable in loop
by hippo (Abbot) on Aug 08, 2017 at 08:22 UTC

    The @Array_Vals goes out of scope as (each iteration of) the loop ends. If you use strict (and you always should - especially while learning) then that code won't even compile.

      Apologies, the last curly bracket was in the wrong place. It should have been:

      my @Array_of_ALL_Vals; for my $iloop (0 .. 10){ my @Array_Vals; . Code in here to populate @Array_of_Vals . push @Array_of_ALL_Vals,\@Array_Vals; }

        With your code, the my declaration will create a fresh @Array_Vals every trip around the loop.

        If you want to see your data structure, use Data::Dumper to show it:

        my @Array_of_ALL_Vals; for my $iloop (0 .. 10){ my @Array_Vals; . Code in here to populate @Array_of_Vals . push @Array_of_ALL_Vals,\@Array_Vals; print Dumper \@Array_of_ALL_Vals; }
        ... the last curly bracket was in the wrong place. It should have been ...

        It's possible and preferable for you to correct your OPwith a note to explain that a correction had been made; see How do I change/delete my post? See the Edit link in the upper right corner of your OP or in the lower right set of links in one of your replies.

        Give a man a fish:  <%-{-{-{-<

Re: declare my variable in loop
by thanos1983 (Curate) on Aug 08, 2017 at 09:51 UTC

    Hello gauss76,

    Since you are asking on how to improve your code. One possible way could be also making it faster:

    #! /usr/bin/perl use strict; use warnings; use feature 'say'; # use Benchmark qw(:all) ; # WindowsOS use Benchmark::Forking qw( timethese cmpthese ); # UnixOS sub for_loop { for my $iloop (0 .. 10){ say $iloop; } return; } sub while_loop { my @numbers = qw( 1 2 3 4 5 6 7 8 9 10 ); while (defined(my $int = shift @numbers)) { say $int; } return; } my $results = timethese(1000000, { While => \&while_loop, ForEach => \&for_loop, }, 'none'); cmpthese( $results ); __END__ $ perl s/iter While ForEach While 2.32 -- -14% ForEach 1.98 17% --

    One minor note here to point out, notice that the array @numbers will be destroyed due to shift. If you do not need to reuse the array then that could be a possible way of moving forward.

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: declare my variable in loop
by sundialsvc4 (Abbot) on Aug 08, 2017 at 14:40 UTC

    To be absolutely clear about what happens here ... when a variable “goes out of scope” in this way, the data which it formerly referred to (probably) becomes unreferenced, and therefore eligible for eventual cleanup by Perl’s “garbage collector.”   Conceptually, every memory object has a reference-count and becomes eligible for cleanup when that count becomes zero.   Garbage collection happens opportunistically, since of course it does represent time-consuming overhead, but it means that you don’t have to worry about explicitly reclaiming memory.   All interpreted languages and many compiled ones offer a similar feature.

      A few languages either don't have references (e.g. Perl4, MATLAB/GNU Octave) or restrict them to one-per-object (Rust) and avoid the garbage-collection and dangling-reference problems that way. So once again, sundial's sweeping generalizations based on his vast experience are wrong.
      This is wrong. Please ignore the parent post.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1196954]
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2017-08-24 10:49 GMT
Find Nodes?
    Voting Booth?
    Who is your favorite scientist and why?

    Results (367 votes). Check out past polls.