Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Array got modified!

by exilepanda (Pilgrim)
on Oct 10, 2011 at 01:56 UTC ( #930517=perlquestion: print w/replies, xml ) Need Help??
exilepanda has asked for the wisdom of the Perl Monks concerning the following question:

@arr = qw/Foo Bar Blaz/; foreach my $ele ( @arr ) { $ele =~ s/^(.)/x$1/; do_something ( $ele ) ; } print "@arr"; # I got 'xFoo xBar xBlaz'


@arr = qw/Foo Bar Blaz/; foreach my $ele ( @arr ) { my $copy = $ele ; $copy =~ s/^(.)/x$1/; do_something ( $copy ) ; } print "@arr"; # I got 'Foo Bar Blaz'
I just found that, in CODE1, the array elements will change after the run. However, I suppose that $ele is a copy from the array, but seems it behaves like a reference. But if I try print ref $ele it returns nothing so its not reference. Anyway, CODE2 is what I would expect.

So, I just want to know:

1. Is this normal for the being in CODE1 or I missed something? 
2. Is this happen in all Perl version? ( I am using 5.10 now) and was using 5.6~5.8 before 
Because I am considering to have some revision on modules I wrote before now...

Replies are listed 'Best First'.
Re: Array got modified!
by Util (Priest) on Oct 10, 2011 at 02:24 UTC
    1. Yes it is normal
    2. Yes, all versions.
    From `perldoc perlsyn`, in the "Foreach Loops" section:
    If any element of LIST is an lvalue, you can modify it by modifying VAR inside the loop. Conversely, if any element of LIST is NOT an lvalue, any attempt to modify that element will fail. In other words, the foreach loop index variable is an implicit alias for each item in the list that you're looping over.
      O!! Thx man! This explains a lot. Never notice for yrs.
      So I am gonna change my habit to do this way :
      @arr = qw/Foo Bar Blaz/; foreach ( @arr ) { my $ele = $_; $ele =~ s/^(.)/x$1/; } # or this while ( my $ele = <@arr> ) { $ele =~ s/^(.)/x$1/; } print "@arr"; # still 'Foo Bar Blaz'
      Would you suggest which one is better, or any well suggested practice?

        Could you explain, in your own words, what does the while ( my $ele = <@arr> ) { do?

        Once you do, go check the docs!

        It may seem to do what you seem to want if you are unlucky enough and the @arr doesn't contain anything interesting to the diamond operator, but even then it's horribly inefficient.

        Enoch was right!
        Enjoy the last years of Rome.

        What is the point in editing $ele, if you then discard it?

        Never mind, I did not read the post properly.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://930517]
Approved by keszler
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (11)
As of 2018-04-26 18:25 GMT
Find Nodes?
    Voting Booth?