Perl / perl5

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

[no subject] #6698

Closed p5pRT closed 20 years ago

p5pRT commented 20 years ago

Migrated from rt.perl.org#23302 (status was 'resolved')

Searchable as RT23302$

p5pRT commented 20 years ago

From va0hs001@sneakemail.com

Created by zmcj0g5a001@sneakemail.com

There seems to be something peculiar with the calling context imposed by the block passed to reduce. In the following two snippets\, the [eval] returns a different result depending upon whether the result is assigned to a variable or not. This implies\, and in some tests can be shown (see http​://perlmonks.com/index.pl?node_id=283304 and the follow-ups) to that the (last?) expression in the block is being evaluated in a void context\, but there are also counter examples. Again\, I'd like to have offered a patch but looking at the XS code leaves me without a clue as to what might be wrong. Sorry.

The bug\, with minor variations\, has been confirmed using List​::Util v1.07 and 1.11 with Perl v5.6.1\, 5.8.0\, 5.8.1\, and 5.8.1-rc2 under Win32 and some flavours of Linux.

---snippet 1 --- use List​::Util qw[ reduce ];

print reduce{ eval "$a + $b" } 1\,2\,3; Use of uninitialized value in concatenation (.) or string at ...

3 --- end of snippet 1--- --- snippet 2 --- use List​::Util qw[ reduce ];

print reduce{ my $n = eval "$a + $b" } 1\,2\,3;

6 --- end of snippet 2 ---

Perl Info ``` Flags: category=utilities severity=medium Site configuration information for perl v5.8.0: Configured by ActiveState at Fri Nov 8 00:53:50 2002. Summary of my perl5 (revision 5 version 8 subversion 0) configuration: Platform: osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread uname='' config_args='undef' hint=recommended, useposix=true, d_sigaction=undef usethreads=undef use5005threads=undef useithreads=define usemultiplicity=define useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cl', ccflags ='-nologo -Gf -W3 -MD -DNDEBUG -O1 -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX', optimize='-MD -DNDEBUG -O1', cppflags='-DWIN32' ccversion='', gccversion='', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='link', ldflags ='-nologo -nodefaultlib -release -libpath:"D:/Perl\lib\CORE" -machine:x86' libpth="D:\Perl\lib\CORE" libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib perllibs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl58.lib gnulibc_version='undef' Dynamic Linking: dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -release -libpath:"D:/Perl\lib\CORE" -machine:x86' Locally applied patches: ACTIVEPERL_LOCAL_PATCHES_ENTRY @INC for perl v5.8.0: d:/Perl/lib d:/Perl/site/lib . Environment for perl v5.8.0: HOME (unset) LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=d:\perl\bin; PERL_BADLANG (unset) SHELL (unset) _________________________________________________________________ It's fast, it's easy and it's free. Get MSN Messenger today! http://www.msn.co.uk/messenger ```
p5pRT commented 20 years ago

From @rgarcia

va0hs001@​sneakemail.com (via RT) wrote​:

use List​::Util qw[ reduce ];

print reduce{ eval "$a + $b" } 1\,2\,3;

Are you aware that this is equivalent to   print reduce{ eval " + " } 1\,2\,3; and that this eval throws a syntax error ?

p5pRT commented 20 years ago

From @RandalSchwartz

"Rafael" == Rafael Garcia-Suarez \raphel\.garcia\-suarez@​hexaflux\.com writes​:

Rafael> va0hs001@​sneakemail.com (via RT) wrote​:

use List​::Util qw[ reduce ];

print reduce{ eval "$a + $b" } 1\,2\,3;

Rafael> Are you aware that this is equivalent to Rafael> print reduce{ eval " + " } 1\,2\,3; Rafael> and that this eval throws a syntax error ?

That's not my reading of the docs. reduce() definitely wants to have $a and $b as placeholders\, standing for the first value and second value on the first iteration\, and then the result and the next new value on every subsequent iteration.

No\, something odd is going on... I've been following the thread on perlmonks as well.

-- Randal L. Schwartz - Stonehenge Consulting Services\, Inc. - +1 503 777 0095 \merlyn@&#8203;stonehenge\.com \<URL​:http​://www.stonehenge.com/merlyn/> Perl/Unix/security consulting\, Technical writing\, Comedy\, etc. etc. See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

p5pRT commented 20 years ago

From ek9635@sbc.com

-----Original Message----- From​: Rafael Garcia-Suarez [mailto​:raphel.garcia-suarez@​hexaflux.com] Sent​: Wednesday\, August 13\, 2003 8​:48 AM

va0hs001@​sneakemail.com (via RT) wrote​:

use List​::Util qw[ reduce ];

print reduce{ eval "$a + $b" } 1\,2\,3;

Are you aware that this is equivalent to print reduce{ eval " + " } 1\,2\,3; and that this eval throws a syntax error ?

Here's something even more fun​:

(shamelessly taken from the Perlmonks discussion on it)

perl -MList​::Util -e 'print List​::Util​::reduce { print "a = $a\, b = $b\n"; eval "$a + $b" } 1\, 2\, 3;' a = 1\, b = 2 a = \, b = 3 semi-panic​: attempt to dup freed string at -e line 1. Segmentation fault (core dumped)

This works​:

perl -MList​::Util -e 'print List​::Util​::reduce { print "a = $a\, b = $b\n"; $c = eval "$a + $b"; $c } 1\, 2\, 3;' a = 1\, b = 2 a = 3\, b = 3 6

perl -MList​::Util -e 'print List​::Util->VERSION()\, "\n"' 1.11

This is on perl 5.6.1. I haven't tried it out on 5.8.x yet.

p5pRT commented 20 years ago

From @demerphq

va0hs001@​sneakemail.com (via RT) wrote​:

use List​::Util qw[ reduce ];

print reduce{ eval "$a + $b" } 1\,2\,3;

Are you aware that this is equivalent to print reduce{ eval " + " } 1\,2\,3; and that this eval throws a syntax error ?

No it isnt equivelent to that at all.

$a and $b are set by reduce before the block is evaluated.

As can be readily verified by​:

use List​::Util qw[ reduce ]; print reduce{ print "$a $b\n"; eval "$a + $b" } 1\,2\,3;

Outputs​:

1 2 3 3 6

p5pRT commented 20 years ago

From @demerphq

As can be readily verified by​:

use List​::Util qw[ reduce ]; print reduce{ print "$a $b\n"; eval "$a + $b" } 1\,2\,3;

Outputs​:

1 2 3 3 6

But apparently I dont get the errors the others do. :-)

$List​::Util​::VERSION = 1.07

This is perl\, v5.6.1 built for MSWin32-x86-multi-thread (with 1 registered patch\, see perl -V for more detail)

Copyright 1987-2001\, Larry Wall

Binary build 633 provided by ActiveState Corp. http​://www.ActiveState.com

p5pRT commented 20 years ago

From enache@rdslink.ro

On Wed\, Aug 13\, 2003 a.d.\, va0hs001@​sneakemail.com (via RT) wrote​:

print reduce{ eval "$a + $b" } 1\,2\,3; Use of uninitialized value in concatenation (.) or string at ...

3

Please try the patch below. (Yes\, it will make things slower -- but notice that this bug affects not only C\<eval "$a + $b">\, but ex.

$ perl -MList​::Util=reduce -le 'sub a { $a + $b } print reduce { a } 1\,2\,3' 3

Just pointing the gp_sv field to the SV from the stack (as List​::Util​::reduce does) is _not_ right. smarter/nicer solutions probably exist.

Regards\, Adi

Inline Patch ```diff diff -rup /arc/bleadperl/ext/List/Util/t/reduce.t ./ext/List/Util/t/reduce.t --- /arc/bleadperl/ext/List/Util/t/reduce.t 2002-11-03 13:23:42.000000000 +0200 +++ ./ext/List/Util/t/reduce.t 2003-08-14 00:58:08.000000000 +0300 @@ -16,7 +16,7 @@ BEGIN { use List::Util qw(reduce min); -print "1..9\n"; +print "1..10\n"; print "not " if defined reduce {}; print "ok 1\n"; @@ -56,3 +56,5 @@ print "${x}ok 9\n"; sub foobar { reduce { (defined(wantarray) && !wantarray) ? '' : 'not ' } 0,1,2,3 } +print "not " unless (reduce {eval "$a+$b"} 1,2,3) == 6; +print "ok 10\n"; diff -rup /arc/bleadperl/ext/List/Util/Util.xs ./ext/List/Util/Util.xs --- /arc/bleadperl/ext/List/Util/Util.xs 2003-06-11 09:48:17.000000000 +0300 +++ ./ext/List/Util/Util.xs 2003-08-14 00:50:01.000000000 +0300 @@ -244,7 +244,7 @@ CODE: if (!CvDEPTH(cv)) (void)SvREFCNT_inc(cv); for(index = 2 ; index < items ; index++) { - GvSV(agv) = ret; + SvSetSV(GvSV(agv),ret); GvSV(bgv) = ST(index); PL_op = reducecop; CALLRUNOPS(aTHX); ```
p5pRT commented 20 years ago

From @demerphq

Please try the patch below. (Yes\, it will make things slower -- but notice that this bug affects not only C\<eval "$a + $b">\, but ex.

$ perl -MList​::Util=reduce -le 'sub a { $a + $b } print reduce { a } 1\,2\,3' 3

Just pointing the gp_sv field to the SV from the stack (as List​::Util​::reduce does) is _not_ right. smarter/nicer solutions probably exist.

Yep\, it works fine for me now.

Yves

p5pRT commented 20 years ago

From Robin.Barker@npl.co.uk

The attached patch fixes the latest List​::Util and adds a test.

Robin

-----Original Message----- From​: Orton\, Yves [mailto​:yves.orton@​de.mci.com] Sent​: 13 August 2003 15​:22 To​: 'Rafael Garcia-Suarez'; perl5-porters@​perl.org Subject​: RE​: [perl #23302] [no subject] (reduce / eval arent playing nicel y together)

As can be readily verified by​:

use List​::Util qw[ reduce ]; print reduce{ print "$a $b\n"; eval "$a + $b" } 1\,2\,3;

Outputs​:

1 2 3 3 6

But apparently I dont get the errors the others do. :-)

$List​::Util​::VERSION = 1.07

This is perl\, v5.6.1 built for MSWin32-x86-multi-thread (with 1 registered patch\, see perl -V for more detail)

Copyright 1987-2001\, Larry Wall

Binary build 633 provided by ActiveState Corp. http​://www.ActiveState.com


This e-mail and any attachments may contain confidential and/or privileged material; it is for the intended addressee(s) only. If you are not a named addressee\, you must not use\, retain or disclose such information.

NPL Management Ltd cannot guarantee that the e-mail or any attachments are free from viruses.

NPL Management Ltd. Registered in England and Wales. No​: 2937881 Registered Office​: Teddington\, Middlesex\, United Kingdom TW11 0LW.


p5pRT commented 20 years ago

From Robin.Barker@npl.co.uk

listutileval.gz

p5pRT commented 20 years ago

From @gbarr

On Wed\, 2003-08-13 at 22​:59\, Enache Adrian wrote​:

On Wed\, Aug 13\, 2003 a.d.\, va0hs001@​sneakemail.com (via RT) wrote​:

print reduce{ eval "$a + $b" } 1\,2\,3; Use of uninitialized value in concatenation (.) or string at ...

3

Please try the patch below.

This is close\, but not right as it will result in $a being modified when the sub returns. Later today I will release 1.12 with a fix for this.

Graham.

(Yes\, it will make things slower -- but notice that this bug affects not only C\<eval "$a + $b">\, but ex.

$ perl -MList​::Util=reduce -le 'sub a { $a + $b } print reduce { a } 1\,2\,3' 3

Just pointing the gp_sv field to the SV from the stack (as List​::Util​::reduce does) is _not_ right. smarter/nicer solutions probably exist.

Regards\, Adi

diff -rup /arc/bleadperl/ext/List/Util/t/reduce.t ./ext/List/Util/t/reduce.t --- /arc/bleadperl/ext/List/Util/t/reduce.t 2002-11-03 13​:23​:42.000000000 +0200 +++ ./ext/List/Util/t/reduce.t 2003-08-14 00​:58​:08.000000000 +0300 @​@​ -16\,7 +16\,7 @​@​ BEGIN {

use List​::Util qw(reduce min);

-print "1..9\n"; +print "1..10\n";

print "not " if defined reduce {}; print "ok 1\n"; @​@​ -56\,3 +56\,5 @​@​ print "${x}ok 9\n";

sub foobar { reduce { (defined(wantarray) && !wantarray) ? '' : 'not ' } 0\,1\,2\,3 }

+print "not " unless (reduce {eval "$a+$b"} 1\,2\,3) == 6; +print "ok 10\n"; diff -rup /arc/bleadperl/ext/List/Util/Util.xs ./ext/List/Util/Util.xs --- /arc/bleadperl/ext/List/Util/Util.xs 2003-06-11 09​:48​:17.000000000 +0300 +++ ./ext/List/Util/Util.xs 2003-08-14 00​:50​:01.000000000 +0300 @​@​ -244\,7 +244\,7 @​@​ CODE​: if (!CvDEPTH(cv)) (void)SvREFCNT_inc(cv); for(index = 2 ; index \< items ; index++) { - GvSV(agv) = ret; + SvSetSV(GvSV(agv)\,ret); GvSV(bgv) = ST(index); PL_op = reducecop; CALLRUNOPS(aTHX);

p5pRT commented 20 years ago

From @rgs

Resolved by change 20700 (Update to Scalar-List-Utils 1.12)

p5pRT commented 20 years ago

@rgs - Status changed from 'new' to 'resolved'