in reply to Re: Changing array by changing $_?
in thread Changing array by changing $_?

The reason map (and for/foreach and grep) make an alias instead of a copy is speed. A lot code, probably a majority of the code, doesn't modify $_ inside a map or grep; slightly less code will not modify $_ (or the loop variable) inside a for/foreach.

If don't plan to modify $_, having an alias instead of a copy means the data doesn't have to be copied, saving memory and speed. This benefits everyone; the only case where extra code is needed is where one modifies $_ without the intention to modify the original array. That code has to do the copy explicitely.

IMO, the right choice has been made.

Replies are listed 'Best First'.
Re^3: Changing array by changing $_?
by repellent (Priest) on Oct 13, 2008 at 17:25 UTC
    I would also like to add that this feature, in addition to speed, is a godsend in terms of saving (memory) space. Why make a copy of a variable when we only need to read it? Some other languages do make copies implicitly.

    When dealing with large datasets, the programmer needs to be aware of this behavior (of any programming language, for that matter) to ensure scalability.
Re^3: Changing array by changing $_?
by gone2015 (Deacon) on Oct 13, 2008 at 15:20 UTC

    IMHO this is something that could usefully be rendered safer by strict, or similar. When it's useful to be able to modify $_ (or named alias) a little extra 'decoration' would not be material, and would highlight the use of this feature. The rest of the time it would reduce follicular wear and tear !

      I do not agree.

      If you need help in this department, write a Perl::Critic rule that checks whether you make a copy as the first line of your map/grep/for/foreach/sub block. Your suggestion would mean slowing down almost any scalar assignment done.

        For lexicals, couldn't the check be done at compile-time?

        OK. I can just about imagine how assignment to an ordinary scalar and assignment via an alias would be the same at run-time -- at run-time it doesn't much matter where the pointer to the SV has come from.

        However, I would have thought that the two must be distinguished at compile time -- something has to take care of the implied dereference -- for no run-time penalty.

        I realise that there are plenty of other traps for the new and the unwary -- but I can still remember the pain of learning about this one !