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


in reply to Dereference string in foreach

Turn on strict and warnings and you'll see why.

use warnings; use strict; my $sref = \$string; foreach $string ( @array_of_strings ) { print $$sref; } $ perl sref_o.pl Global symbol "$string" requires explicit package name at sref_o.pl li +ne 4. Global symbol "$string" requires explicit package name at sref_o.pl li +ne 5. Global symbol "@array_of_strings" requires explicit package name at sr +ef_o.pl line 5. Execution of sref_o.pl aborted due to compilation errors.


Peter L. Berghold -- Unix Professional
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg

Replies are listed 'Best First'.
Re^2: Dereference string in foreach
by Anonymous Monk on Feb 13, 2013 at 21:06 UTC

    You don't need to be an utter cowdawg towards the OP -- strict and warnings are irrelevant to his issue.

    I don't fully grok the semantics of foreach but I suspect the correct answer is as follows:

    $sref = \$string sets $sref to point to the variable $string. All is well here. But then foreach enters the picture and localises $string -- this $string is only available to the inner loop. $sref continues pointing to the $string in the outer loop. Testing this without the string reference:

    my $string = "I'm still here"; say $string; my @array_of_strings = qw/foo bar baz quux/; foreach $string ( @array_of_strings ) { say $string; } say $string; # output I'm still here foo bar baz quux I'm still here

    Yep, looks like what I described. Now, if you add the $sref, you'll notice it'll print the outer loop value for the whole time -- it points to the wrong $string.

      Thanks for that answer.
      Though quite some time has passed since I last read the corresponding paragraph in perldoc, I wouldn't have expected that the reference still points to the variable outside of the loop since it is used within the loop.

      All variables have been previouly defined using my (i.e. in the beginning of the script).

          You don't need to be an utter cowdawg towards the OP -- strict and warnings are irrelevant to his issue.

      I wasn't being mean, ornery or cantankerous. Take what I said at face value. If strict and warnings were turned on (as I showed) the problem would have shown itself very clearly.


      Peter L. Berghold -- Unix Professional
      Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
        > If strict and warnings were turned on (as I showed) the problem would have shown itself very clearly.

        Nope, it's another problem just at the same place.

        Using my fixes the errors but not the OP's problem, which is foreach localization and aliasing.

        use warnings; use strict; my $string; my @array_of_strings=1..3; my $sref = \$string; foreach $string ( @array_of_strings ) { print $$sref; } __END__ Use of uninitialized value in print at - line 8. Use of uninitialized value in print at - line 8. Use of uninitialized value in print at - line 8. lanx@nc10-ubuntu:~$

        Cheers Rolf

        Oh. I seem to have missed the part where the problem showed itself very clearly. I'm still not quite sure where it is shown, actually.

        Anyway, sorry about that. I did not particularly mean to lash out at you -- your advice just seemed like one of those "you must use strict even for the smallest script" posts that I sometimes see.