Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.94k stars 554 forks source link

for does not properly localize $\ #6557

Closed p5pRT closed 12 years ago

p5pRT commented 21 years ago

Migrated from rt.perl.org#22613 (status was 'rejected')

Searchable as RT22613$

p5pRT commented 21 years ago

From perl-5.8.0@ton.iguana.be

Created by perl-5.8.0@ton.iguana.be

perl -we '$\="4\n"; for $\ (1) { print 5 }' 54

I expected 51

Perl Info ``` Flags: category=core severity=low Site configuration information for perl v5.8.0: Configured by ton at Tue Nov 12 01:56:18 CET 2002. Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration: Platform: osname=linux, osvers=2.4.19, archname=i686-linux-thread-multi-64int-ld uname='linux quasar 2.4.19 #5 wed oct 2 02:34:25 cest 2002 i686 unknown ' config_args='' hint=recommended, useposix=true, d_sigaction=define usethreads=define use5005threads=undef useithreads=define usemultiplicity=define useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=define use64bitall=undef uselongdouble=define usemymalloc=y, bincompat5005=undef Compiler: cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2 -fomit-frame-pointer', cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -I/usr/local/include' ccversion='', gccversion='2.95.3 20010315 (release)', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long long', ivsize=8, nvtype='long double', nvsize=12, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -lndbm -ldb -ldl -lm -lpthread -lc -lposix -lcrypt -lutil perllibs=-lnsl -ldl -lm -lpthread -lc -lposix -lcrypt -lutil libc=/lib/libc-2.2.4.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.2.4' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Locally applied patches: @INC for perl v5.8.0: /usr/lib/perl5/5.8.0/i686-linux-thread-multi-64int-ld /usr/lib/perl5/5.8.0 /usr/lib/perl5/site_perl/5.8.0/i686-linux-thread-multi-64int-ld /usr/lib/perl5/site_perl/5.8.0 /usr/lib/perl5/site_perl . Environment for perl v5.8.0: HOME=/home/ton LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/ton/bin.Linux:/home/ton/bin:/home/ton/bin.SampleSetup:/usr/local/bin:/usr/local/sbin:/usr/local/jre/bin:/home/oracle/product/9.0.1/bin:/usr/local/ar/bin:/usr/games/bin:/usr/X11R6/bin:/usr/share/bin:/usr/bin:/usr/sbin:/bin:/sbin:. PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 21 years ago

From alex@chmrr.net

On Sat\, 2003-06-07 at 16​:28\, perl-5.8.0@​ton.iguana.be (via RT) wrote​:

perl -we '$\="4\n"; for $\ (1) { print 5 }' 54

I expected 51 I'm fairly sure this has the same cause as one of the oldest bugs in the book\, #948. Observe the following​:

perl -we '$\="4\n"; for $\ (1) {print "Current \$\\ is $\; endline->";}'

  My understanding of why this happens may very well be flawed (I used this bug to get my feet wet with the core code) but goes as follows​: the value which lives in the stash is the one that gets localized\, not the global PL_ors_sv variable (which is the one actually internally used used during printing) Thus while printing $\ explicitly shows the right value\, the internal value that matters hasn't realized the change.

I'm unclear on how to best go about fixing this\, though. Last time this bug was brought up\, there was some discussion on disallowing tie() on $\ and $\, -- but tie is just one symptom of this problem. This bug is another. I'd be happy to try my hand at fixing this\, but I've no clue which direction to start in. - Alex

-- Networking -- only one letter away from not working.

p5pRT commented 21 years ago

From @rgs

Alex Vandiver wrote​:

On Sat\, 2003-06-07 at 16​:28\, perl-5.8.0@​ton.iguana.be (via RT) wrote​:

perl -we '$\="4\n"; for $\ (1) { print 5 }' 54

I expected 51 I'm fairly sure this has the same cause as one of the oldest bugs in the book\, #948. Observe the following​:

perl -we '$\="4\n"; for $\ (1) {print "Current \$\\ is $\; endline->";}'

My understanding of why this happens may very well be flawed (I used this bug to get my feet wet with the core code) but goes as follows​: the value which lives in the stash is the one that gets localized\, not the global PL_ors_sv variable (which is the one actually internally used used during printing) Thus while printing $\ explicitly shows the right value\, the internal value that matters hasn't realized the change.

You're correct :

./perl -e '$\="4\n"; for $\ (1) { print $\; }' 14

I'm unclear on how to best go about fixing this\, though. Last time this bug was brought up\, there was some discussion on disallowing tie() on $\ and $\, -- but tie is just one symptom of this problem. This bug is another. I'd be happy to try my hand at fixing this\, but I've no clue which direction to start in.

The code that creates the iterator variable for a foreach loop doesn't propagate magic to it -- for some value of "propagate" to be defined.

I'm wondering whether we should\, at the contrary\, document this behavior\, making clear that the iterator is a new variable.

See perlsyn :

  The C\ loop iterates over a normal list value and sets the   variable VAR to be each element of the list in turn. If the variable   is preceded with the keyword C\\, then it is lexically scoped\, and   is therefore visible only within the loop. Otherwise\, the variable is   implicitly local to the loop and regains its former value upon exiting   the loop. If the variable was previously declared with C\\, it uses   that variable instead of the global one\, but it's still localized to   the loop. This implicit localisation occurs I\ in a C\   loop.

p5pRT commented 21 years ago

From @rgarcia

I wrote​:

./perl -e '$\="4\n"; for $\ (1) { print $\; }' 14

Thinking a bit more about this\, I think this is not a bug. Reason : the loop variable is an alias to the value the loop iterates on (as documented in perlsyn). So it's normal that no magic is added to those values.

If there's no sign of disagreement\, I'll close this bug and add a regression test corresponding to the one-liner above.

p5pRT commented 21 years ago

From me-02@ton.iguana.be

On Tue\, Jun 10\, 2003 at 07​:46​:25AM -0000\, Rafael Garcia-Suarez wrote​:

I wrote​:

./perl -e '$\="4\n"; for $\ (1) { print $\; }' 14

Thinking a bit more about this\, I think this is not a bug. Reason : the loop variable is an alias to the value the loop iterates on (as documented in perlsyn). So it's normal that no magic is added to those values.

I think you're looking at it too much in terms of the way it's implemented instead of what it's supposed to mean.

to me print should be like

sub print {   raw_print join($\, \,@​_).$\; }

or as real code (abusing syswrite and assuming it just works)​:

perl -le 'sub pr {   syswrite(STDOUT\, join($\, \,@​_).$\); } for $\ ("1\n") {   pr "waf"; }'

which prints​:

waf1

The fact that the real print is done with an internal char * and the (original) $\ maps to it by magic is an implementation detail. And the fact that this breaks when localizing with a for feels like a bug to me.

p5pRT commented 21 years ago

From @rgs

me-02@​ton.iguana.be wrote​:

I think you're looking at it too much in terms of the way it's implemented instead of what it's supposed to mean.

That's very possible.

p5pRT commented 21 years ago

From @abigail

On Tue\, Jun 10\, 2003 at 09​:41​:59AM +0200\, Rafael Garcia-Suarez wrote​:

I wrote​:

./perl -e '$\="4\n"; for $\ (1) { print $\; }' 14

Thinking a bit more about this\, I think this is not a bug. Reason : the loop variable is an alias to the value the loop iterates on (as documented in perlsyn). So it's normal that no magic is added to those values.

But that's not true. For *some* variables\, magic is still attached. For instance\, $"​:

  $ perl -wle '@​a = (1\, 2); $"="\, "; for $" ("--") {print "@​a"}'   1--2

However​:

  $ perl -wle '@​a = (1\, 2); $\,="\, "; for $\, ("--") {print @​a}'   1\, 2

I can live with the fact no magic can be associated with localized versions of those variables - but an illogic inconsistency irks me.

Abigail

p5pRT commented 21 years ago

From enache@rdslink.ro

On Wed\, Jul 09\, 2003 at 12​:29​:03PM +0200\, Abigail wrote​:

But that's not true. For *some* variables\, magic is still attached. For instance\, $"​:

$ perl \-wle '@​a = \(1\, 2\); $"="\, "; for $" \("\-\-"\) \{print "@​a"\}'
1\-\-2

Yup\, that's it. $" is *not* a magic variable.

Regards\, Adi

However​:

$ perl \-wle '@​a = \(1\, 2\); $\,="\, "; for $\, \("\-\-"\) \{print @​a\}'
1\, 2

I can live with the fact no magic can be associated with localized versions of those variables - but an illogic inconsistency irks me.

Abigail

p5pRT commented 21 years ago

From @abigail

On Wed\, Jul 09\, 2003 at 10​:34​:47PM +0300\, Enache Adrian wrote​:

On Wed\, Jul 09\, 2003 at 12​:29​:03PM +0200\, Abigail wrote​:

But that's not true. For *some* variables\, magic is still attached. For instance\, $"​:

$ perl \-wle '@​a = \(1\, 2\); $"="\, "; for $" \("\-\-"\) \{print "@​a"\}'
1\-\-2

Yup\, that's it. $" is *not* a magic variable.

Maybe in the implementation it isn't. But for a user $" is as magical as $\,

Abigail

p5pRT commented 12 years ago

From @jkeenan

On Sat Jun 07 13​:28​:55 2003\, perl-5.8.0@​ton.iguana.be wrote​:

perl -we '$\="4\n"; for $\ (1) { print 5 }' 54

I expected 51

Since you are attempting to use a Perl special variable ($\) as a loop iterator variable. You are assuming that it will be assigned to like $_.

However\, 'perldoc perlsyn' warns against doing this​:

##### "foreach" probably won't do what you expect if VAR is a tied or other special variable. Don't do that either. #####

This documentation was added in 1998. So I don't think this constitutes a bug.

Thank you very much. Jim Keenan

p5pRT commented 12 years ago

@iabyn - Status changed from 'open' to 'rejected'