When the following code could have side effects?
@some = map { s/xxx/y/; $_ } @some;
The perlcritic explains it as dangerous, because for example:
@other = map { s/xxx/y/; $_ } @some;
and the members of the @some
got also modified. Understand. I have the BPB book, and it shows the above with the example
@pm_files_without_pl_files
= grep { s/.pm\z/.pl/xms && !-e } @pm_files;
and also I read the chapter "List Processing Side Effects" / "Never modify $_ in a list function." and its followers. Also i know the /r
.
To be clear (as much is possible with my terrible english):
In the 1st example the main point is modifying the original @some
.
The question is about:
@some = map { s/xxx/y/; $_ } @some;
causing some unwanted side-effects? If yes, when?Looking for an answer what goes a bit deeper as some "perl beginner's book" - therefore still doesn't accepted any current answer. ;)
Accessing global variable inside function: The ways to access the global variable inside functions are: Using global keyword. Using array GLOBALS[var_name]: It stores all global variables in an array called $GLOBALS[var_name]. Var_name is the name of the variable.
Some predefined variables in PHP are "superglobals", which means that they are always accessible, regardless of scope - and you can access them from any function, class or file without having to do anything special. The PHP superglobal variables are: $GLOBALS. $_SERVER.
To access the global variable within a function, use the GLOBAL keyword before the variable. However, these variables can be directly accessed or used outside the function without any keyword.
The global keyword imports variables from the global scope into the local scope of a function.
One of the mottos of perl has always been TIMTOWTDI: there is more than one way to do it. If two ways have the same end result, they're equally correct. That doesn't mean there aren't reasons to prefer one way over the other.
In the first case, it would be more obvious (to me, YMMV) to do something like
s/xxx/y/ for @some;
This is mainly because it's communicating intend better. for
suggests it's all about the side effect, whereas map
suggests it's about the return value. While functionally identical, this should be much easier to understand for your fellow programmer (and probably for yourself in 6 months from now).
There's more than one way, but some are better than others.
Code like your example:
@some = map { s/xxx/y/; $_ } @some;
should be avoided because it's redundant and confusing. It looks like the assignment on the left should be doing something, even though it's actually a no-op. Indeed, just writing:
map { s/xxx/y/; $_ } @some;
would have the exact same effect, as would:
map { s/xxx/y/ } @some;
This version at least has the virtue of making it (reasonably) clear that the return value of map
is being ignored, and that the actual purpose of the statement is to modify @some
in place.
But of course, as Leon has already pointed out, by far the clearest and most idiomatic way of writing this would be:
s/xxx/y/ for @some;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With