palkia has asked for the wisdom of the Perl Monks concerning the following question:

hello

knowing the "my" initializes a var doesn't tell me much about a case in which:
for my $index (@array)
{
my $var = whatever;
...
}
(as I plan on doing)

can doing so cause any problems ? (pretty sure it does in java, but can't remember nor try)
will the $var be re-initialized for every cycle of the loop,
or will perl be "smart" enough to preform the line without the "my" after the 1st cycle ?
and if it would re-initialize, will this cause any visible problems or merely cause some memory inefficiency ?
(and yes, I am planning on using both strict and warnings)

also, if this does cause a problem is there an alternative to "my" that will behave as mentioned ?

I'm so tired of throwing vars and their "my" back to before outermost loop (just in case).
I know I can just run some tests and try to figure it out myself, but I didn't want to risk having it work for some cases and confusing me later for others, under the false assurance that it's bulletproof (and so I'm here ^^)

thank you very much

Replies are listed 'Best First'.
Re: my within a loop
by GrandFather (Saint) on Apr 05, 2011 at 02:34 UTC

    There are just two cases to be concerned about: 1/ $var is local to the loop, 2/ $var is global to the loop.

    1/ If $var is local to the loop the desired behaviour is that you get a fresh version of $var each time through the loop. In that case use a my declaration where the first value is assigned to $var within the loop.

    2/ If you want $var to retain some previous value from one iteration of the loop to the next (maybe you are looking for a largest value or something) then $var should be global to the loop. In that case use a my declaration just before the loop and assign an appropriate initial value if required.

    True laziness is hard work
Re: my within a loop
by wind (Priest) on Apr 05, 2011 at 02:28 UTC

    Yes, my $var will go out of scope after each iteration. If you want it to stay, you must declare it outside of your for loop.

    You also might find this illuminating: Lexical scoping like a fox. Someone else shared it with regard to another thread today.

Re: my within a loop
by CountZero (Bishop) on Apr 05, 2011 at 06:41 UTC
    In modern versions of Perl (I use 5.12) you can use the state keyword.

    From the docs:

    state declares a lexically scoped variable, just like my does. However, those variables will never be reinitialized, contrary to lexical variables that are reinitialized each time their enclosing block is entered. state variables are enabled only when the use feature "state" pragma is in effect.

    But take care: even if you leave the loop entirely and re-enter it later, the state variable will still have maintained its last value!

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      Using a state variable doesn't seem appropriate here. What the right thing to do here depends on "whatever". If "whatever" is the same all the time, and the value of the variable doesn't change, moving it outside of the loop is the right thing to do. Otherwise, it should be left as is. It's a common case, and perl actually optimizes this - from a language POV, you get a new variable each time. Internally, structures are reused if possible.
Re: my within a loop
by ikegami (Patriarch) on Apr 05, 2011 at 03:38 UTC
    That code is perfectly fine. In effect, a new var is created every time. As an optimisation, the same variable is reused when possible.