Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When modifying $_ can be wrong?

Tags:

perl

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:

  • could the 1st example @some = map { s/xxx/y/; $_ } @some; causing some unwanted side-effects? If yes, when?
  • or it is just the "not recommented" way (but harmless otherwise)?

Looking for an answer what goes a bit deeper as some "perl beginner's book" - therefore still doesn't accepted any current answer. ;)

like image 763
cajwine Avatar asked Aug 10 '15 16:08

cajwine


People also ask

How can use global variable inside function in PHP?

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.

What is global variable in PHP with example?

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.

How can we define a variable accessible in functions of a PHP script?

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.

What is global keyword in PHP?

The global keyword imports variables from the global scope into the local scope of a function.


2 Answers

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.

like image 74
Leon Timmermans Avatar answered Oct 20 '22 19:10

Leon Timmermans


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;
like image 43
Ilmari Karonen Avatar answered Oct 20 '22 17:10

Ilmari Karonen