Perl / perl5

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

overloaded iterator <> does not recognize list context #3823

Closed p5pRT closed 15 years ago

p5pRT commented 23 years ago

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

Searchable as RT6748$

p5pRT commented 23 years ago

From arjen.bax@cmg.nl

Created by arjen.bax@cmg.nl

When the iteration operator \<> is overloaded with

  use overload '\<>' => 'method';

the invoked method does not recognize when it is invoked from list context\, i.e. wantarray always returns FALSE. If the method is invoked immediately\, without overloading\, it recognizes its list environment.

I added a small package (Count.pm) to demonstrate the problem. It implements a class that counts from 0 to 9\, overloading the \<> operator to method iterate. The following oneliners should all produce the same output '0123456789'\, but the 4th\, where the \<> is called in list context only produces '0' (1\, 2 and 3 are OK).

  1% perl -MCount -wle 'my $x=new Count;print while $x->iterate'   2% perl -MCount -wle 'my $x=new Count;print for $x->iterate'   3% perl -MCount -wle 'my $x=new Count;print while \<$x>'   4% perl -MCount -wle 'my $x=new Count;print for \<$x>'

Hope this is enough information...

Regards\, Arjen Bax -- CMG Noord-Nederland B.V. Sector Telecommunications & Utilities Postbus 70237\, 9704 AE Groningen Tel. (050)52 19 500\, Fax (050)52 19 504 \<http​://www.cmg.nl> \<http​://www.cmg.com>

Adding manpower to a late software project makes it later.

Perl Info ``` Flags: category=core severity=medium Site configuration information for perl v5.6.1: Configured by Fifer at Thu Dec 21 21:37:10 2000. Summary of my perl5 (revision 5.0 version 6 subversion 1) configuration: Platform: osname=cygwin, osvers=1.1.6(0.3032), archname=cygwin uname='cygwin_nt-5.0 fifer 1.1.6(0.3032) 2000-11-21 21:00 i686 unknown ' config_args='-de' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=undef d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef Compiler: cc='gcc', ccflags ='-DPERL_USE_SAFE_PUTENV -DHAS_SBRK_PROTO -fno-strict-aliasing', optimize='-O2', cppflags='-DPERL_USE_SAFE_PUTENV -DHAS_SBRK_PROTO -fno-strict-aliasing' ccversion='', gccversion='2.95.2-5 19991024 (cygwin experimental)', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=4 alignbytes=8, usemymalloc=y, prototype=define Linker and Libraries: ld='ld2', ldflags =' -s -L/usr/local/lib' libpth=/usr/local/lib /usr/lib /lib libs=-lgdbm -lcrypt perllibs=-lcrypt libc=/usr/lib/libc.a, so=dll, useshrplib=true, libperl=libperl5_6_1.a Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' -s' cccdlflags=' ', lddlflags=' -s -L/usr/local/lib' Locally applied patches: v5.6.1-TRIAL1 @INC for perl v5.6.1: /usr/local/lib/site_perl/5.6.1 /usr/lib/perl5/5.6.1/cygwin /usr/lib/perl5/5.6.1 /usr/lib/perl5/site_perl/5.6.1/cygwin /usr/lib/perl5/site_perl/5.6.1 /usr/lib/perl5/site_perl . Environment for perl v5.6.1: HOME=/users/abax LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/usr/bin:/usr/local/bin:/c/texmf/miktex/bin:/c/bin:/c/usr/scripts:/c/us r/local/bin:/c/WINNT/system32:/c/WINNT:/users/abax/bin PERL5LIB=/usr/local/lib/site_perl/5.6.1 PERL_BADLANG (unset) SHELL=/usr/bin/bash ---END OF MESSAGE ```
p5pRT commented 23 years ago

From arjen.bax@cmg.nl

Count.pm

p5pRT commented 15 years ago

From module@renee-baecker.de

When the iteration operator \<> is overloaded with

use overload '\<>' => 'method';

the invoked method does not recognize when it is invoked from list context\, i.e. wantarray always returns FALSE. If the method is invoked immediately\, without overloading\, it recognizes its list environment.

I added a small package (Count.pm) to demonstrate the problem. It implements a class that counts from 0 to 9\, overloading the \<> operator to method iterate. The following oneliners should all produce the same output '0123456789'\, but the 4th\, where the \<> is called in list context only produces '0' (1\, 2 and 3 are OK).

1% perl -MCount -wle 'my $x=new Count;print while $x->iterate' 2% perl -MCount -wle 'my $x=new Count;print for $x->iterate' 3% perl -MCount -wle 'my $x=new Count;print while \<$x>' 4% perl -MCount -wle 'my $x=new Count;print for \<$x>'

There was a discussion about that in 1999 and Ilya said that the context shouldn't be recognized in overloaded operators.

The discussion can be found here​: http​://markmail.org/message/ffd6sunhu6mfchfz

p5pRT commented 15 years ago

From [Unknown Contact. See original ticket]

When the iteration operator \<> is overloaded with

use overload '\<>' => 'method';

the invoked method does not recognize when it is invoked from list context\, i.e. wantarray always returns FALSE. If the method is invoked immediately\, without overloading\, it recognizes its list environment.

I added a small package (Count.pm) to demonstrate the problem. It implements a class that counts from 0 to 9\, overloading the \<> operator to method iterate. The following oneliners should all produce the same output '0123456789'\, but the 4th\, where the \<> is called in list context only produces '0' (1\, 2 and 3 are OK).

1% perl -MCount -wle 'my $x=new Count;print while $x->iterate' 2% perl -MCount -wle 'my $x=new Count;print for $x->iterate' 3% perl -MCount -wle 'my $x=new Count;print while \<$x>' 4% perl -MCount -wle 'my $x=new Count;print for \<$x>'

There was a discussion about that in 1999 and Ilya said that the context shouldn't be recognized in overloaded operators.

The discussion can be found here​: http​://markmail.org/message/ffd6sunhu6mfchfz

p5pRT commented 15 years ago

module@renee-baecker.de - Status changed from 'open' to 'resolved'

p5pRT commented 15 years ago

From module@renee-baecker.de

When the iteration operator \<> is overloaded with

use overload '\<>' => 'method';

the invoked method does not recognize when it is invoked from list context\, i.e. wantarray always returns FALSE. If the method is invoked immediately\, without overloading\, it recognizes its list environment.

I added a small package (Count.pm) to demonstrate the problem. It implements a class that counts from 0 to 9\, overloading the \<> operator to method iterate. The following oneliners should all produce the same output '0123456789'\, but the 4th\, where the \<> is called in list context only produces '0' (1\, 2 and 3 are OK).

1% perl -MCount -wle 'my $x=new Count;print while $x->iterate' 2% perl -MCount -wle 'my $x=new Count;print for $x->iterate' 3% perl -MCount -wle 'my $x=new Count;print while \<$x>' 4% perl -MCount -wle 'my $x=new Count;print for \<$x>'

There was a discussion about that in 1999 and Ilya said that the context shouldn't be recognized in overloaded operators.

The discussion can be found here​: http​://markmail.org/message/ffd6sunhu6mfchfz

p5pRT commented 15 years ago

From [Unknown Contact. See original ticket]

When the iteration operator \<> is overloaded with

use overload '\<>' => 'method';

the invoked method does not recognize when it is invoked from list context\, i.e. wantarray always returns FALSE. If the method is invoked immediately\, without overloading\, it recognizes its list environment.

I added a small package (Count.pm) to demonstrate the problem. It implements a class that counts from 0 to 9\, overloading the \<> operator to method iterate. The following oneliners should all produce the same output '0123456789'\, but the 4th\, where the \<> is called in list context only produces '0' (1\, 2 and 3 are OK).

1% perl -MCount -wle 'my $x=new Count;print while $x->iterate' 2% perl -MCount -wle 'my $x=new Count;print for $x->iterate' 3% perl -MCount -wle 'my $x=new Count;print while \<$x>' 4% perl -MCount -wle 'my $x=new Count;print for \<$x>'

There was a discussion about that in 1999 and Ilya said that the context shouldn't be recognized in overloaded operators.

The discussion can be found here​: http​://markmail.org/message/ffd6sunhu6mfchfz

p5pRT commented 15 years ago

From @demerphq

2008/11/17 reneeb via RT \perlbug\-comment@&#8203;perl\.org​:

When the iteration operator \<> is overloaded with

use overload '\<>' => 'method';

the invoked method does not recognize when it is invoked from list context\, i.e. wantarray always returns FALSE. If the method is invoked immediately\, without overloading\, it recognizes its list environment.

I added a small package (Count.pm) to demonstrate the problem. It implements a class that counts from 0 to 9\, overloading the \<> operator to method iterate. The following oneliners should all produce the same output '0123456789'\, but the 4th\, where the \<> is called in list context only produces '0' (1\, 2 and 3 are OK).

1% perl -MCount -wle 'my $x=new Count;print while $x->iterate' 2% perl -MCount -wle 'my $x=new Count;print for $x->iterate' 3% perl -MCount -wle 'my $x=new Count;print while \<$x>' 4% perl -MCount -wle 'my $x=new Count;print for \<$x>'

There was a discussion about that in 1999 and Ilya said that the context shouldn't be recognized in overloaded operators.

The discussion can be found here​: http​://markmail.org/message/ffd6sunhu6mfchfz

The only thing is that discussion doesn't really address the \<> operator. All of that discussion addressed binary operators\, and if it did address the \<> operator i think it would have been clear that it is actually needed in at least that case\, and any other operator that can return lists.

cheers\, Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 15 years ago

From tchrist@perl.com

On Tue\, 18 Nov 2008 12​:43​:41 +0100 demerphq \demerphq@&#8203;gmail\.com wrote​:

2008/11/17 reneeb via RT \perlbug\-comment@&#8203;perl\.org​:

When the iteration operator \<> is overloaded with

use overload '\<>' => 'method';

the invoked method does not recognize when it is invoked from list context\, i.e. wantarray always returns FALSE. If the method is invoked immediately\, without overloading\, it recognizes its list environment.

I added a small package (Count.pm) to demonstrate the problem. It implements a class that counts from 0 to 9\, overloading the \<> operator to method iterate. The following oneliners should all produce the same output '0123456789'\, but the 4th\, where the \<> is called in list context only produces '0' (1\, 2 and 3 are OK).

1% perl -MCount -wle 'my $x=new Count;print while $x->iterate' 2% perl -MCount -wle 'my $x=new Count;print for $x->iterate' 3% perl -MCount -wle 'my $x=new Count;print while \<$x>' 4% perl -MCount -wle 'my $x=new Count;print for \<$x>'

Well\, you can try this​:

  package Count;   sub TIEHANDLE {   my $count = 0;   return bless sub {   return () if $count > 9;   return wantarray   ? ($count .. 9)   : $count ++ ;   } => (shift() || __PACKAGE__);   }   *iterate = *READLINE = sub { goto &{ $_[0] } };   sub new {   require Carp;   Carp​::croak("I'm fit to be tied");   }   1;

And then

  % perl -MCount -wle 'tie local *CTR => "Count"; for (1..10) { print \ }'   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789

  % perl -MCount -wle 'tie local *CTR => "Count"; for (1..10) { print scalar \ }'   0   1   2   3   4   5   6   7   8   9

  % perl -MCount -wle 'my $x=tie local *CTR => "Count"; for (1..10) { print $x->iterate }'   Name "main​::CTR" used only once​: possible typo at -e line 1.   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789

  % perl -MCount -wle 'my $x=tie local *CTR => "Count"; for (1..10) { print scalar $x->iterate }'   Name "main​::CTR" used only once​: possible typo at -e line 1.   0   1   2   3   4   5   6   7   8   9

  % perl -MCount -wle 'tie local *CTR => "Count"; for (1..10) { print (tied(*CTR)->iterate) }'   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789   0123456789

There was a discussion about that in 1999 and Ilya said that the context shouldn't be recognized in overloaded operators.

The discussion can be found here​: http​://markmail.org/message/ffd6sunhu6mfchfz

The only thing is that discussion doesn't really address the \<> operator. All of that discussion addressed binary operators\, and if it did address the \<> operator i think it would have been clear that it is actually needed in at least that case\, and any other operator that can return lists.

Apart from =\, those scant few operators that *can* return lists (provided they've been used in list context) are only​:

  0​: + print +localtime; # gag me w/a spoon   1​: x @​trips = (@​a) x 3; # but not x=   2​: \, @​c = (@​a\, @​b);   3​: .. @​trey = 1.2..3.4; # (1\,2\,3)​: of course!   3​: .. @​nums = (0 .. 9);   4​: ... @​nums = (0 ... 9); # same IFF list context   5​: && "true" && @​a # but not &&=   6​: || @​a || "whatever" # but not ||=   7​: // undef // localtime() # but not //=   8​: // print /[aeiouy]/i && //g; # prints all vowels\, or none   8​: // @​many_codons = /.../g;   9​: \\ @​refrefs = \\localtime; # mirabile visu   9​: \ @​numrefs = \localtime; # nearly so   10​: ?​: @​max = (@​a > @​b) ? @​a : @​b;   11​: ?? @​once_codons = ?...?g; # highlander match   12​: \<> @​stuff = \; # readline()   13​: \<> use lib \<~/stdlib>; # glob()   13​: \<> @​zones = \<America/{Chicago\,Denver\,Phoenix\,Los_Angeles}>;   14​: -> @​fils = threads->list; # double-entendre   15​: => use constant MEALS => # how to feed a hobbit   qw(

  Coffee
  Breakfast   Second-Breakfast

  Brunch
  Lunch
  Munch

  Tea/Tapas

  Dinner
  Supper   Snacker   Snooker   );

And arguably​:

  16​: @​{} @​ans = @​{ f("x") };   17​: %{} @​ans = %{ f("x") };   18​: &{} @​ans = &{ f("x") };

I shan't visit named listops like sort\, map\, grep\, or reverse\, nor the sillyops like or and and or and and or.

--tom