in reply to Re: Possible bug with array pointer
in thread Possible bug with array pointer

Thank you!

I've been programming perl for almost 20 years and didn't know that!

I guess I've never actually modified the assigned foreach-variable or never used the array afterwards! What are the odds ;-)

The lesson learned: You never stop learning!

-----BEGIN PERL GEEK CODE BLOCK----- Version: 0.01 P++>*$c--->---P6 > R >++++$M+>+++$O+++>+++$MA->+++$E > PU->++BD->-C+>+$D+>+$S->+++X >+WP >+++MO!PP n?CO--PO!>!(!)o?G!A--OLC--OLCC--OLJ--Ee !Ev-Eon-uL++>*uB!uS!uH-uo!w->!m+ ------END PERL GEEK CODE BLOCK------

Replies are listed 'Best First'.
Re^3: Possible bug with array pointer
by Athanasius (Archbishop) on Jan 11, 2017 at 03:34 UTC

    Hello jockel,

    A standard idiom (see Re: Containing 'use lib' statements in modules to their own namespace) for removing (“breaking”) the alias is to assign the aliased variable to a lexical variable inside the loop:

    use strict; use warnings; my $arrayref = ['A','_B','C']; for my $str (@$arrayref) { print "BEFORE: str = $str\n"; } for (@$arrayref) { my $str = $_; $str =~ s/^_//; print "INNER: str = $str\n"; } for my $str (@$arrayref) { print "AFTER: str = $str\n"; }

    Output:

    13:30 >perl 1738_SoPW.pl BEFORE: str = A BEFORE: str = _B BEFORE: str = C INNER: str = A INNER: str = B INNER: str = C AFTER: str = A AFTER: str = _B AFTER: str = C 13:30 >

    BTW, an underscore character has no special meaning in a regex, so it doesn’t need to be escaped. Also, in the absence of an /m modifier, ^ can only ever match once, at the beginning of the string, so the /g modifier is redundant.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Thank you for your tips =)

      I solved it by copying the referenced array to a "normal array" before the foreach. TMTOWTDI =)

      I usually escape more than needed. Better safe than sorry. About the redundancy with ^ and /g, I totally agree!

Re^3: Possible bug with array pointer
by Marshall (Canon) on Jan 11, 2017 at 01:40 UTC
    BTW, you do not need the braces to access a simple scalar reference as an array:
    foreach my $str (@$arrayref) { print "BEFORE: str = $str\n"; }
    will work just as well.
    The extra braces are needed when there is a subscript. @{$arrayref->[2]}

      Thanks. That I actually knew, but in my opinion it's more clear to read when using braces.

      And in the real world case where I was hit by this unknown "oddity" the code looked like this, before the change.

      foreach my $var (@{$self->get('SAMPLEIDS')}) { $var =~ s/_//g; push(@temp_SAMPLEIDS, $var); }

        Hi jockel,

        If you've got Perl v5.14 or later, note that there's also s///r:

        use 5.014; my $sampleids = ['A','_B','C']; my @temp_SAMPLEIDS; foreach my $var (@$sampleids) { push(@temp_SAMPLEIDS, $var =~ s/_//gr); } # OR my @temp2_SAMPLEIDS = map {s/_//gr} @$sampleids; use Data::Dumper; print Dumper($sampleids, \@temp_SAMPLEIDS, \@temp2_SAMPLEIDS); __END__ $VAR1 = [ 'A', '_B', 'C' ]; $VAR2 = [ 'A', 'B', 'C' ]; $VAR3 = [ 'A', 'B', 'C' ];

        Hope this helps,
        -- Hauke D