in reply to Last undefines a for loop's itererator?

Why isn't $picture set after the loop terminates?
Because at loop exit, $picture is restored to whatever value it had before loop entry (in this case undef); or more precisely: within the loop, $picture is aliased to each value in turn; outsise the loop it is not aliased and so the name $picture once again refers to the original value.

Dave.

  • Comment on Re: Last undefines a for loop's itererator?

Replies are listed 'Best First'.
Re^2: Last undefines a for loop's itererator?
by Animator (Hermit) on Nov 12, 2005 at 11:20 UTC

    Some additional comment on this: you really don't want $picture to be set outside the loop. It would make debbuging really hard.

    As [id://dave_the_m] said: it is an alias. Meaning if you do $picture = "something else"; then the original value will change. Limiting the effect of the alias to the foreach-block (and everything that is called via the foreach-block and still is in the lexical-scope of the variable) is a really good thing. (Because it reduces the code you need to look at when debugging.)

    Also note that it is not last that undefines it. For example: for my $x (0 .. 3) { } print $x;==> it won't print 3.

    (Ofcourse in your example you won't see the difference after doing an assignment because you are using a temporary list.)(It does matter. Sort seems to return an alias.)

    Update: added comment about last
    Update2: stroke some incorrect text.

Re^2: Last undefines a for loop's itererator?
by pg (Canon) on Nov 13, 2005 at 02:39 UTC

    Just add one thing, with use strict and warnings, Perl does give error: (I added my in front of $picture, so that the error at line 15 is isolated)

    use strict; use warnings; my $match = '1995_Olga_goes_to_Egypt'; my @pictures = qw{1995/1995_Olga_first_time_in_Cyprus/06330004.JPG 1995/1995_Olga_goes_to_Egypt/QD0017004.JPG}; foreach my $picture (sort @pictures) { print "Debug: $picture\n"; if ($picture =~ m/$match/) { print "Matched, $picture\n"; last; } } print "Result: $picture\n";

    This gives:

    Global symbol "$picture" requires explicit package name at math1.pl li +ne 15. Execution of math1.pl aborted due to compilation errors.
      That's not relevant to the issue here. The following strict-compliant program illustrates the issue:
      use strict; use warnings; my $x; for $x (1 .. 3) { last if $x == 2 } print $x;
      which prints
      Use of uninitialized value in print at - line 5.

        On the contrary, it's very relevant. In fact, the original question is I think a great example of the importance of using strict and warnings.

        In the original code, the loop variable $picture was not pre-declared outside the loop using my (as you did for your $x). Had the OP run his code under use strict;, it would have died at compile time, perhaps prompting the OP to take a closer look at his code - exactly the thing I want use strict; to do for me.

        Even with strict-compliant code similiar to yours, the OP would have gotten an informative message, rather then just an empty string, when using use warnings; - namely, the Use of uninitialized value in print message. There is it, staring him in the face - $picture is not initialized.

        It's true that the warning does not explain why there is a problem. But in my experience, understanding exactly where the problem lies, is half-way to solving it.