Skip Menu |
Report information
Id: 115834
Status: rejected
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: sp [at] smartspb.net
Cc:
AdminCc:

Operating System: All
PatchStatus: (no value)
Severity: Wishlist
Type:
Perl Version: 5.16.1
Fixed In: (no value)



CC: sp [...] uskr.smartspb.net
Subject: Successfull match $_[0] =~ /foo(.+)/ overrides $_[0] if function called as foo($1)
Date: Mon, 19 Nov 2012 21:17:41 +0400 (MSK)
To: perlbug [...] perl.org
From: sp [...] smartspb.net
Download (untitled) / with headers
text/plain 3.9k
This is a bug report for perl from sp@smartspb.net, generated with the help of perlbug 1.39 running under perl 5.16.1. ----------------------------------------------------------------- Successfull match $_[0] =~ /foo(.+)/ inside subroutine overrides $_[0] if subroutine called as foo($1). ###### script ###### sp@uskr:~/3 (1570) cat u.pl use strict; use warnings; use feature qw(:all); sub foo { say ' before =~ $_[0] is ', "'$_[0]'"; $_[0] =~ /foo(.+)/; say ' after =~ $_[0] is ', "'$_[0]'", ' and $1 is ', "'$1'"; } # ok say 'call foo("foo123");'; foo('foo123'); # at least strange say 'call foo($1);'; 'barfoo123' =~ /(foo.+)/ && foo($1); ###### output ###### sp@uskr:~/3 (1571) perl u.pl call foo("foo123"); before =~ $_[0] is 'foo123' after =~ $_[0] is 'foo123' and $1 is '123' call foo($1); before =~ $_[0] is 'foo123' after =~ $_[0] is '123' and $1 is '123' sp@uskr:~/3 (1572) ###### summary ###### I'm not sure is that bug or feature. I could not find something describing such things in docs. [Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=low --- Site configuration information for perl 5.16.1: Configured by sp at Thu Oct 11 12:45:42 MSK 2012. Summary of my perl5 (revision 5 version 16 subversion 1) configuration: Platform: osname=freebsd, osvers=9.0-release, archname=amd64-freebsd uname='freebsd uskr 9.0-release freebsd 9.0-release #0: tue jan 3 07:46:30 utc 2012 root@farrell.cse.buffalo.edu:usrobjusrsrcsysgeneric amd64 ' config_args='-de -Dprefix=/site/perl5/perls/perl-5.16.1 -Aeval:scriptdir=/site/perl5/perls/perl-5.16.1/bin' hint=recommended, useposix=true, d_sigaction=define useithreads=undef, usemultiplicity=undef useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include', optimize='-O', cppflags='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion='', gccversion='4.2.1 20070831 patched [FreeBSD]', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='cc', ldflags ='-Wl,-E -fstack-protector -L/usr/local/lib' libpth=/usr/lib /usr/local/lib libs=-lm -lcrypt -lutil -lc perllibs=-lm -lcrypt -lutil -lc libc=, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' ' cccdlflags='-DPIC -fPIC', lddlflags='-shared -L/usr/local/lib -fstack-protector' Locally applied patches: --- @INC for perl 5.16.1: /site/perl5/perls/perl-5.16.1/lib/site_perl/5.16.1/amd64-freebsd /site/perl5/perls/perl-5.16.1/lib/site_perl/5.16.1 /site/perl5/perls/perl-5.16.1/lib/5.16.1/amd64-freebsd /site/perl5/perls/perl-5.16.1/lib/5.16.1 . --- Environment for perl 5.16.1: HOME=/home/sp LANG=ru_RU.UTF-8 LANGUAGE (unset) LC_ALL=ru_RU.UTF-8 LC_COLLATE=ru_RU.UTF-8 LC_CTYPE=ru_RU.UTF-8 LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/site/perl5/bin:/site/perl5/perls/perl-5.16.1/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin PERLBREW_BASHRC_VERSION=0.52 PERLBREW_HOME=/home/sp/.perlbrew PERLBREW_MANPATH=/site/perl5/perls/perl-5.16.1/man PERLBREW_PATH=/site/perl5/bin:/site/perl5/perls/perl-5.16.1/bin PERLBREW_PERL=perl-5.16.1 PERLBREW_ROOT=/site/perl5 PERLBREW_VERSION=0.52 PERL_BADLANG (unset) SHELL=/usr/local/bin/bash
Subject: Re: [perl #115834] Successfull match $_[0] =~ /foo(.+)/ overrides $_[0] if function called as foo($1)
Date: Tue, 20 Nov 2012 22:57:24 +0100
To: perl5-porters [...] perl.org
From: Lukas Mai <l.mai [...] web.de>
Download (untitled) / with headers
text/plain 1.7k
On 19.11.2012 18:17, sp@smartspb.net (via RT) wrote: Show quoted text
> Successfull match $_[0] =~ /foo(.+)/ inside subroutine > overrides $_[0] if subroutine called as foo($1). > > ###### script ###### sp@uskr:~/3 (1570) cat u.pl > use strict; use warnings; use feature qw(:all); > > sub foo { > say ' before =~ $_[0] is ', "'$_[0]'"; > $_[0] =~ /foo(.+)/; > say ' after =~ $_[0] is ', "'$_[0]'", ' and $1 is ', "'$1'"; > } > > # ok > > say 'call foo("foo123");'; > foo('foo123'); > > # at least strange > > say 'call foo($1);'; > 'barfoo123' =~ /(foo.+)/ && foo($1); > > ###### output ###### sp@uskr:~/3 (1571) perl u.pl > > call foo("foo123"); > before =~ $_[0] is 'foo123' > after =~ $_[0] is 'foo123' and $1 is '123' > call foo($1); > before =~ $_[0] is 'foo123' > after =~ $_[0] is '123' and $1 is '123' > > sp@uskr:~/3 (1572) > > ###### summary ###### > > I'm not sure is that bug or feature. > I could not find something describing such things in docs.
This is not a bug. Quoting perldoc perlsub: Any arguments passed in show up in the array @_ . Therefore, if you called a function with two arguments, those would be stored in $_[0] and $_[1] . The array @_ is a local array, but its elements are aliases for the actual scalar parameters. In particular, if an element $_[0] is updated, the corresponding argument is updated (or an error occurs if it is not updatable). If an argument is an array or hash element which did not exist when the function was called, that element is created only when (and if) it is modified or a reference to it is taken. (Some earlier versions of Perl created the element whether or not the element was assigned to.) Assigning to the whole array @_ removes that aliasing, and does not update any arguments. -- Lukas Mai <l.mai@web.de>
Subject: Re: [perl #115834] Successfull match $_[0] =~ /foo(.+)/ overrides$_[0] if function called as foo($1)
Date: Wed, 21 Nov 2012 01:20:19 +0100
To: perl5-porters [...] perl.org
From: "Dr.Ruud" <rvtol+usenet [...] isolution.nl>
Download (untitled) / with headers
text/plain 1.9k
On 2012-11-20 22:57, Lukas Mai wrote: Show quoted text
> On 19.11.2012 18:17, sp@smartspb.net (via RT) wrote:
Show quoted text
>> Successfull match $_[0] =~ /foo(.+)/ inside subroutine >> overrides $_[0] if subroutine called as foo($1). >> >> ###### script ###### sp@uskr:~/3 (1570) cat u.pl >> use strict; use warnings; use feature qw(:all); >> >> sub foo { >> say ' before =~ $_[0] is ', "'$_[0]'"; >> $_[0] =~ /foo(.+)/; >> say ' after =~ $_[0] is ', "'$_[0]'", ' and $1 is ', "'$1'"; >> } >> >> # ok >> >> say 'call foo("foo123");'; >> foo('foo123'); >> >> # at least strange >> >> say 'call foo($1);'; >> 'barfoo123' =~ /(foo.+)/ && foo($1); >> >> ###### output ###### sp@uskr:~/3 (1571) perl u.pl >> >> call foo("foo123"); >> before =~ $_[0] is 'foo123' >> after =~ $_[0] is 'foo123' and $1 is '123' >> call foo($1); >> before =~ $_[0] is 'foo123' >> after =~ $_[0] is '123' and $1 is '123' >> >> sp@uskr:~/3 (1572) >> >> ###### summary ###### >> >> I'm not sure is that bug or feature. >> I could not find something describing such things in docs.
> > This is not a bug. Quoting perldoc perlsub: > > Any arguments passed in show up in the array @_ . Therefore, if you > called a function with two arguments, those would be stored in $_[0] and > $_[1] . The array @_ is a local array, but its elements are aliases for > the actual scalar parameters. In particular, if an element $_[0] is > updated, the corresponding argument is updated (or an error occurs if it > is not updatable). If an argument is an array or hash element which did > not exist when the function was called, that element is created only > when (and if) it is modified or a reference to it is taken. (Some > earlier versions of Perl created the element whether or not the element > was assigned to.) Assigning to the whole array @_ removes that aliasing, > and does not update any arguments.
Workaround: local $1. (at the start of the sub) Do we need a feature that auto-localizes the numbered capture variables for subs? -- Ruud
CC: perl5-porters [...] perl.org
Subject: Re: [perl #115834] Successfull match $_[0] =~ /foo(.+)/ overrides$_[0] if function called as foo($1)
Date: Tue, 20 Nov 2012 18:23:32 -0600
To: "Dr.Ruud" <rvtol+usenet [...] isolution.nl>
From: Jesse Luehrs <doy [...] tozt.net>
Download (untitled) / with headers
text/plain 2.4k
On Wed, Nov 21, 2012 at 01:20:19AM +0100, Dr.Ruud wrote: Show quoted text
> On 2012-11-20 22:57, Lukas Mai wrote:
> >On 19.11.2012 18:17, sp@smartspb.net (via RT) wrote:
>
> >>Successfull match $_[0] =~ /foo(.+)/ inside subroutine > >>overrides $_[0] if subroutine called as foo($1). > >> > >>###### script ###### sp@uskr:~/3 (1570) cat u.pl > >>use strict; use warnings; use feature qw(:all); > >> > >>sub foo { > >> say ' before =~ $_[0] is ', "'$_[0]'"; > >> $_[0] =~ /foo(.+)/; > >> say ' after =~ $_[0] is ', "'$_[0]'", ' and $1 is ', "'$1'"; > >>} > >> > >># ok > >> > >>say 'call foo("foo123");'; > >>foo('foo123'); > >> > >># at least strange > >> > >>say 'call foo($1);'; > >>'barfoo123' =~ /(foo.+)/ && foo($1); > >> > >>###### output ###### sp@uskr:~/3 (1571) perl u.pl > >> > >>call foo("foo123"); > >> before =~ $_[0] is 'foo123' > >> after =~ $_[0] is 'foo123' and $1 is '123' > >>call foo($1); > >> before =~ $_[0] is 'foo123' > >> after =~ $_[0] is '123' and $1 is '123' > >> > >>sp@uskr:~/3 (1572) > >> > >>###### summary ###### > >> > >>I'm not sure is that bug or feature. > >>I could not find something describing such things in docs.
> > > >This is not a bug. Quoting perldoc perlsub: > > > >Any arguments passed in show up in the array @_ . Therefore, if you > >called a function with two arguments, those would be stored in $_[0] and > >$_[1] . The array @_ is a local array, but its elements are aliases for > >the actual scalar parameters. In particular, if an element $_[0] is > >updated, the corresponding argument is updated (or an error occurs if it > >is not updatable). If an argument is an array or hash element which did > >not exist when the function was called, that element is created only > >when (and if) it is modified or a reference to it is taken. (Some > >earlier versions of Perl created the element whether or not the element > >was assigned to.) Assigning to the whole array @_ removes that aliasing, > >and does not update any arguments.
> > Workaround: local $1. (at the start of the sub) > > Do we need a feature that auto-localizes the numbered capture > variables for subs?
No. The behavior here is the same behavior as my $a; sub foo { say $_[0]; $a = "bar"; say $_[0]; } $a = "foo"; foo($a); which prints foo bar It has nothing to do with capture variables, it happens for any variable at all, because it is caused by the aliasing, not anything about the variable itself. -doy
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 423b
This is an issue which comes up perenially, see http://thread.gmane.org/gmane.comp.lang.perl.perl5.porters/1607 for an earlier 'bug' report. I do feel that the current behaviour is confusing, if every time a new programmer hits a seeming bug it requires a detailed explanation from one of the perl5-porters about why it's meant to work like that. If it's really unchangeable then calling foo($1) should issue a warning.
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 859b
On Tue Nov 20 16:26:18 2012, doy@tozt.net wrote: Show quoted text
>The behavior here is the same behavior as
I believe it's not the same behaviour as the example you gave. Expanding the code with one more final 'say': my $a; sub foo { say $_[0]; $a = "bar"; say $_[0]; } $a = "foo"; foo($a); say $a; This prints foo bar bar. But the analogous code using $1 sub foo { say $_[0]; 'bar' =~ /(bar)/; say $_[0]; } 'foo' =~ /(foo)/; foo($1); say $1; prints foo bar foo. So while in the case of a global variable you set the value seen by the caller - which makes sense - here $1 is aliased enough to cause weird effects inside the subroutine, yet somehow local enough for these effects to disappear when the subroutine exits. This halfway house is what causes the confusion IMHO.
CC: perl5-porters [...] perl.org
Subject: Re: [perl #115834] Successfull match $_[0] =~ /foo(.+)/ overrides $_[0] if function called as foo($1)
Date: Sun, 25 Nov 2012 13:01:34 -0600
To: Ed Avis via RT <perlbug-followup [...] perl.org>
From: Jesse Luehrs <doy [...] tozt.net>
Download (untitled) / with headers
text/plain 1.4k
On Wed, Nov 21, 2012 at 03:55:43AM -0800, Ed Avis via RT wrote: Show quoted text
> On Tue Nov 20 16:26:18 2012, doy@tozt.net wrote: >
> >The behavior here is the same behavior as
> > I believe it's not the same behaviour as the example you gave. > Expanding the code with one more final 'say': > > my $a; > sub foo { > say $_[0]; > $a = "bar"; > say $_[0]; > } > $a = "foo"; > foo($a); > say $a; > > This prints foo bar bar. But the analogous code using $1 > > sub foo { > say $_[0]; > 'bar' =~ /(bar)/; > say $_[0]; > } > 'foo' =~ /(foo)/; > foo($1); > say $1; > > prints foo bar foo. So while in the case of a global variable you set > the value seen by the caller - which makes sense - here $1 is aliased > enough to cause weird effects inside the subroutine, yet somehow local > enough for these effects to disappear when the subroutine exits. This > halfway house is what causes the confusion IMHO.
This is just a side effect of how $1 works in general - any assignments to capture variables (via a successful match) are implicitly localized: "foo" =~ /(.*)/; warn $1; { "bar" =~ /(.*)/; warn $1; } warn $1; also outputs foo bar foo The current behavior is the only thing that actually makes sense, given the combination of behaviors in this example and the previous one I gave. I do agree that it's fairly confusing, but I really don't know what a better solution to this could possibly be. -doy
Subject: Re: [perl #115834] Successfull match $_[0]=~ /foo(.+)/ overrides$_[0] if function called as foo($1)
Date: Mon, 26 Nov 2012 10:16:26 +0000 (UTC)
To: perl5-porters [...] perl.org
From: Ed Avis <eda [...] waniasset.com>
Download (untitled) / with headers
text/plain 597b
Jesse Luehrs <doy <at> tozt.net> writes: Show quoted text
>This is just a side effect of how $1 works in general - any assignments >to capture variables (via a successful match) are implicitly localized:
Show quoted text
>The current behavior is the only thing that actually makes sense, given >the combination of behaviors in this example and the previous one I >gave. I do agree that it's fairly confusing, but I really don't know >what a better solution to this could possibly be.
I suggest that if we are stuck with the current behaviour, there should be a warning on calls like foo($1). -- Ed Avis <eda@waniasset.com>
To: perl5-porters [...] perl.org
Date: Fri, 15 Dec 2017 05:36:14 +0000
From: Zefram <zefram [...] fysh.org>
Subject: Re: [perl #115834] Successfull match $_[0] =~ /foo(.+)/ overrides $_[0] if function called as foo($1)
With no bug here, this ticket should be closed. -zefram


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org