On the other hand, 'map' will alter the elements of the input list if its block of code modifies $_ in any way, because within the block, $_ functions as a reference to a list element on each iteration -- and of course this is often (usually) how 'map' is used. This can lead to the sort of trouble discussed in this recent meditation, when the input list happens to contain read-only data.
One could argue that this dual result from the mapped code block -- doing in-place editing of the input list and also returning the edited list -- seems to be overdoing it, or is somewhat redundant.
There are many examples of functions (not just in Perl, but generally) that alter the contents of variables in-place and return the original (unaltered) values, or that return altered values and leave the input variables unchanged -- that is, their changes are applied either to the input or to the output, but not to both.
So, maybe this is just a "SoPW" question: is there something that works like 'map' but will not alter the input list? (Or, less intuitively, modify the input list and return the list of unaltered values?)
Apart from cases where the input list contains read-only elements, there are common situations where it would be handy to map one list into another, and have both versions of the list available for later use. To the best of my knowledge, the alternatives for doing this are:
Are there other (better) alternatives? If there aren't, shouldn't there be? Is it just silly of me to yearn for this sort of thing?# ------------------ # FIRST ALTERNATIVE: @out_list = @in_list; map { s/foo(.*?)bar/$1 baz/ } @out_list; # ACK!! ARRGGHH!! map in void context! how bad is that? # (Well, seriously: how bad _is_ that, compared to the # other alternatives below? But let's not digress...) # ------------------- # SECOND ALTERNATIVE: @out_list = map { s/foo(.*?)bar/$1 baz/ } split /\x0/, join("\x0",@in_ +list); # okay, map is used "correctly", and this even works when # the input list and block processing are numeric, but... # seems like too much busy-work just to protect @input_list # from being altered by map. # ------------------ # THIRD ALTERNATIVE: @out_list = map {$j=$_; $j=~s/foo(.*?)bar/$1 baz/; $j} @in_list; # at this point, might as well use "foreach (@input_list) {...}" inste +ad
|
|---|