New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong aliasing of $_ #17119
Comments
From @krokiThis is a bug report for perl from tomash.brechko@gmail.com, Not tested with v5.30, sorry. With v5.28.2 the code below dies with $ echo 1 | perl -e ' f($_) for "a"; sub f { However the problem is more severe: in a real-world program (that I $/ = "\n"; warn() along with the values from @a also prints values read from $fh Still I believe both cases are instances of the same problem: Flags: Site configuration information for perl 5.28.2: Configured by Red Hat, Inc. at Tue Apr 23 08:23:13 UTC 2019. Summary of my perl5 (revision 5 version 28 subversion 2) configuration: Platform: Locally applied patches: @INC for perl 5.28.2: Environment for perl 5.28.2: PATH=/usr/share/Modules/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/home/tomash/.local/bin:/home/tomash/bin:/home/tomash/NOBACKUP/ANDROID/android-studio/bin:/home/tomash/.local/bin:/home/tomash/bin:/home/tomash/NOBACKUP/ANDROID/android-studio/bin |
From @tonycozOn Sun, 04 Aug 2019 02:23:49 -0700, tomash.brechko@gmail.com wrote:
$_ is global, when you alias $_ it's aliased for all code. When you alias $_ to a read-only value, and try to modify $_ the "Modification of a read-only value attempted at -e line 9." error is expected, not unusual. Adding "local $_;" before the while loop in f() fixes this.
Similarly here the while (<$fh>) in f() is modifying the elements of @a in the caller, again local fixes it. $_ can be convenient, but it's like any other global, it can lead to unexpected action at a distance. For complex code I tend to only use $_ with the aliasing done with operators like grep and map, and rarely with the statement modifier foreach. This isn't a bug. Tony |
The RT System itself - Status changed from 'new' to 'open' |
From @krokiOn Sun, 04 Aug 2019 17:06:52 -0700, tonyc wrote:
Ah, I see you point, thanks! Somehow I though that while() should cancel old aliasing, not merely assign through $_, but that was my misunderstanding. Then indeed, postfix for/foreach are quite dangerous. It seems I can't close this myself though... |
From @tonycozOn Sun, 04 Aug 2019 23:05:07 -0700, tomash.brechko@gmail.com wrote:
Closed. Tony |
@tonycoz - Status changed from 'open' to 'rejected' |
From Eirik-Berg.Hanssen@allverden.noOn Wed, Aug 7, 2019 at 5:59 AM Tomash Brechko via RT <
If I may, that seems to be the wrong lesson. There are other constructs The common factor that's dangerous is the C<< while (<...>) { ... } >> Eirik |
From @GrinnzOn Wed, Aug 7, 2019 at 11:46 AM Eirik Berg Hanssen <
Harmless to code that calls it, but code it calls can still be dangerous as -Dan |
From Eirik-Berg.Hanssen@allverden.noOn Wed, Aug 7, 2019 at 5:52 PM Dan Book <grinnz@gmail.com> wrote:
Globals are always trouble, hence the "(relatively)". This particular
But sure, I can agree C<< while (my $l = <...>) { ... } >> (or similar) So, fair enough. When next I encounter this, I'll recommend the lexical Eirik |
From @krokiср, 7 авг. 2019 г. в 19:18, Eirik Berg Hanssen via RT <
For good or bad, we don't always control every function we call, so any f($_) for @a; is a potential risk unless you ensured that f() is safe. The following works: foreach ("a", "b") { Likewise, you can safely nest map/grep/whatever, so I still think it's fair I appreciate your advise, but in the end it boils down to "the feature is |
From @GrinnzOn Thu, Aug 8, 2019 at 12:17 AM Tomash Brechko <tomash.brechko@gmail.com>
Just for the sake of driving the point home, "f() for @a" is the potential -Dan |
From @krokiOn Wed, 07 Aug 2019 21:29:03 -0700, grinnz@gmail.com wrote:
I see what you mean, yet I'd like to disagree. $_ is not just like any other global var, it is special and is meant to be used implicitly. In previous posts I provided some code for the sake of example, but in real life it often looks like f(split /.../) for @a; i.e. $_ is assumed but never mentioned. Even when we do mention it, like @a = map { ">$_<" } @b; then it is an rvalue, and nested foreach/map/grep/etc. do localize $_, so no danger here. And if one ever finds him/herself writing $_ = ...; then I agree that it should be replaced with a real variable (and hopefully not global). Now, when I write sub f { I do not violate "The Protocol" of using $_ implicitly, this is what while(<>) is for. However, as other pointed out, in order to allow f() to be nested in other loops I _have_ to "patch" such _implicit_ use of $_ with preceding _explicit_ local $_, which circumvents the implicit nature of $_ and shows that while(<>) violates "Do The Right Thing" motto. Other implicit looping construct do not have this flaw because they alias, or perhaps otherwise: while(<>) wished to alias too, but it doesn't have rvalues to alias to, so it assigns to $_ *without localizing it first as other constructs do*: for ("old") { Thus I judge it is a bug, but as with some other real bugs in their early denial stage it too may be rejected for a while, not argue against that :). |
Migrated from rt.perl.org#134337 (status was 'rejected')
Searchable as RT134337$
The text was updated successfully, but these errors were encountered: