Perl / perl5

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

'x' forces scalar context on array variables #9526

Closed p5pRT closed 11 years ago

p5pRT commented 16 years ago

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

Searchable as RT59884$

p5pRT commented 16 years ago

From jschneid@redhat.com

Created by jschneid@redhat.com

The 'x' operator forces scalar context on the left operand\, unless that operand is enclosed in parens\, even if the left operand is an array variable.

For example\, the following code fragment prints the string "22"\, rather than the expected four lines of alternating words​:

@​foo = qw(foo bar); print "$_\n" foreach @​foo x 2;

The alternative​:

print "$_\n" foreach qw(foo bar) x 2;

does print the alternating lines.

"perldoc perlop" is not clear on the expected behavior - quoting​:

  In scalar context or if the left operand is not enclosed in parentheses\,   it returns a string consisting of the left operand repeated the number of   times specified by the right operand. In list context\, if the left operand   is enclosed in parentheses or is a list formed by "qw/STRING/"\, it repeats   the list.

It could be read that the behavior is the documented behavior\, but it certainly looks like wrong behavior. It also violates the principal of least surprise. Why should the "x" operator force a particular context on an operand that already has a perfectly good context of its own?

In the event this is not fixed\, I suggest the passage above be amended to​:

  The "x" operator will evaluate its left operand in scalar context\,   unless the left operand is enclosed in parentheses\, or is a list formed   by "qw/STRING/"\, where it will be evaluated in list context. In scalar   context\, it returns a string consisting of the left operand repeated   the number of times specified by the right operand. In list context\,   it repeats the list.

Perl Info ``` Flags: category=core severity=wishlist This perlbug was built using Perl v5.8.8 in the Red Hat build system. It is being executed now by Perl v5.8.8 - Tue Oct 23 12:21:05 EDT 2007. Site configuration information for perl v5.8.8: Configured by Red Hat, Inc. at Tue Oct 23 12:21:05 EDT 2007. Summary of my perl5 (revision 5 version 8 subversion 8) configuration: Platform: osname=linux, osvers=2.6.9-55.0.9.elsmp, archname=i386-linux-thread-multi uname='linux hs20-bc1-6.build.redhat.com 2.6.9-55.0.9.elsmp #1 smp tue sep 25 02:16:15 edt 2007 i686 i686 i386 gnulinux ' config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -Dversion=5.8.8 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dinstallprefix=/usr -Dprefix=/usr -Darchname=i386-linux -Dvendorprefix=/usr -Dsiteprefix=/usr -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dinc_version_list=5.8.7 5.8.6 5.8.5 -Dscriptdir=/usr/bin' 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=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm', optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables', cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include -I/usr/include/gdbm' ccversion='', gccversion='4.1.1 20070105 (Red Hat 4.1.1-52)', 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=8 alignbytes=4, prototype=define Linker and Libraries: ld='gcc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=/lib/libc-2.5.so, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='2.5' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE' cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -L/usr/local/lib' Locally applied patches: @INC for perl v5.8.8: /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.7/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl/5.8.7 /usr/lib/perl5/site_perl/5.8.6 /usr/lib/perl5/site_perl/5.8.5 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.7/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.6/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl/5.8.7 /usr/lib/perl5/vendor_perl/5.8.6 /usr/lib/perl5/vendor_perl/5.8.5 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.8/i386-linux-thread-multi /usr/lib/perl5/5.8.8 . Environment for perl v5.8.8: HOME=/home/jschneid LANG=en_US.UTF-8 LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/usr/lib/qt-3.3/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/sbin:/home/jschneid/bin PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 16 years ago

From @schwern

James Schneider (via RT) wrote​:

The 'x' operator forces scalar context on the left operand\, unless that operand is enclosed in parens\, even if the left operand is an array variable.

For example\, the following code fragment prints the string "22"\, rather than the expected four lines of alternating words​:

@​foo = qw(foo bar); print "$_\n" foreach @​foo x 2;

The alternative​:

print "$_\n" foreach qw(foo bar) x 2;

does print the alternating lines.

I think what you're seeing in the second example is a quirk of Perl's interpretation of "enclosed in parentheses" because I believe once compiled qw(foo bar) and ('foo'\, 'bar') are equivalent.

"perldoc perlop" is not clear on the expected behavior - quoting​:

In scalar context or if the left operand is not enclosed in parentheses\, it returns a string consisting of the left operand repeated the number of times specified by the right operand. In list context\, if the left operand is enclosed in parentheses or is a list formed by "qw/STRING/"\, it repeats the list.

It could be read that the behavior is the documented behavior\, but it certainly looks like wrong behavior. It also violates the principal of least surprise. Why should the "x" operator force a particular context on an operand that already has a perfectly good context of its own?

Because operands don't have context\, only operators. That's sort of like asking\, in English class\, "what context does the word 'right' have"? Words are used in context\, but they do not have an inherent context.

For example\, print evaluates its arguments in list context. When you write C\<\< print $foo >>\, $foo is still being used by print in list context. It just so happens to make no difference.

I suppose one could look at 'x' as being two different operators with the same name. The 'list repeat operator' and the 'scalar repeat operator'. Just like '@​list = qw(1 2 3)' is really using the 'list assignment operator' and '$scalar = qw(1 2 3)' is using the 'scalar assignment operator' at which point my statement that operands don't have context starts to break down.

You're right that C\<\< @​foo x 4 >> is confusing just as C\<\< reverse $foo >> is. This is why the "everything is an object" approach makes more sense. C\<\< @​foo.repeat(4) >> and C\<\< $foo.reverse >> can DWIM better in those cases where the type of the variable\, not the context in which its used\, is more important.

In conclusion\, the 'x' operator probably should just DWIM according to the context in which its used just like every other operator.

  $string = @​foo x 4; # $string = join ''\, map { scalar @​foo } 1..4;   @​list = @​foo x 4; # @​list = map { @​foo } 1..4;

And if you want to force an operand into scalar context\, you do it explicitly.

  @​list = scalar @​foo x 4; # @​list = map { scalar @​foo } 1..4;

But it's too late now. :(

In the event this is not fixed\, I suggest the passage above be amended to​:

The "x" operator will evaluate its left operand in scalar context\, unless the left operand is enclosed in parentheses\, or is a list formed by "qw/STRING/"\, where it will be evaluated in list context. In scalar context\, it returns a string consisting of the left operand repeated the number of times specified by the right operand. In list context\, it repeats the list.

Something like that\, yes. I'd use the "white lie" approach\, start with a simple statement that isn't entirely true and refine\, to allow a series of simpler statements.


Binary "x" is the repetition operator. It repeats the left operand\, as a scalar\, the number of times specified by the right operand.

  $line = '-' x 80; # a string of 80 dashes

If the left operand is enclosed in parenthesis (including a qw/STRING/)\, and the "x" operator is used in list context\, it repeats the list.

  @​dashes = ('-') x 80; # a list of 80 dashes   $line = ('-') x 80; # a string of 80 dashes

If the right operand is zero or negative\, it returns an empty string or empty list\, depending on the context.


-- \ What we learned was if you get confused\, grab someone and swing   them around a few times   -- Life's lessons from square dancing

p5pRT commented 16 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 16 years ago

From @ikegami

On Tue\, Oct 14\, 2008 at 11​:40 AM\, Michael G Schwern \schwern@&#8203;pobox\.comwrote​:

If the left operand is enclosed in parenthesis (including a qw/STRING/)\, and the "x" operator is used in list context\, it repeats the list.

Including qw/STRING/ enclosed in parenthesis?

If the left operand is enclosed in parenthesis or if it's a qw/STRING/\, and if the "x" operator is used in list context\, it repeats the list.

p5pRT commented 16 years ago

From @schwern

Eric Brine wrote​:

On Tue\, Oct 14\, 2008 at 11​:40 AM\, Michael G Schwern \<schwern@​pobox.com \mailto&#8203;:schwern@&#8203;pobox\.com> wrote​:

If the left operand is enclosed in parenthesis \(including a
qw/STRING/\)\, and the "x" operator is used in list context\, it repeats
the list\.

Including qw/STRING/ enclosed in parenthesis?

Ahh\, I see the ambiguity. I want to make it clear that qw/STRING/ isn't a special case in the "x" operator\, but a special parsing case.


If the left operand is enclosed in parenthesis (qw/STRING/ is considered to be enclosed in parenthesis)\, and the "x" operator is used in list context\, it repeats the list.


Speaking of weird exceptions...

$ perl -wle '@​foo = ("a".."b"); $x = @​foo x 2; print $x' 22

$ perl -wle '@​foo = ("a".."b"); $x = (@​foo) x 2; print $x' 22

$ perl -wle '$x = ("a".."b") x 2; print $x' Argument "a" isn't numeric in range (or flip) at -e line 1. Use of uninitialized value in range (or flip) at -e line 1. Argument "b" isn't numeric in range (or flop) at -e line 1. Use of uninitialized value in range (or flop) at -e line 1. 1E01E0

$ perl -wle '$x = (("a".."b") x 2); print $x' Argument "a" isn't numeric in range (or flip) at -e line 1. Use of uninitialized value in range (or flip) at -e line 1. Argument "b" isn't numeric in range (or flop) at -e line 1. Use of uninitialized value in range (or flop) at -e line 1. 1E01E0

Which seems to be a special case of..

$ perl -wle 'print scalar (1..2)' Use of uninitialized value in range (or flip) at -e line 1.

And I'm not going to pretend I understand scalar flip/fop.

-- 54. "Napalm sticks to kids" is *not* a motivational phrase.   -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army   http​://skippyslist.com/list/

p5pRT commented 16 years ago

From perl@nevcal.com

On approximately 10/14/2008 9​:15 AM\, came the following characters from the keyboard of Michael G Schwern​:

Eric Brine wrote​:

On Tue\, Oct 14\, 2008 at 11​:40 AM\, Michael G Schwern \<schwern@​pobox.com \mailto&#8203;:schwern@&#8203;pobox\.com> wrote​:

If the left operand is enclosed in parenthesis \(including a
qw/STRING/\)\, and the "x" operator is used in list context\, it repeats
the list\.

Including qw/STRING/ enclosed in parenthesis?

Ahh\, I see the ambiguity. I want to make it clear that qw/STRING/ isn't a special case in the "x" operator\, but a special parsing case.

------------------------------------------------------- If the left operand is enclosed in parenthesis (qw/STRING/ is considered to be enclosed in parenthesis)\, and the "x" operator is used in list context\, it repeats the list. --------------------------------------------------------

Except for your weird exceptions below\, I was about to suggest saying "If the left operand is a list" (which covers the () syntax\, the qw// syntax\, and excludes the @​foo syntax). Maybe the wording still would cover these weird exceptions appropriately.

But the weird exceptions do point out that the wording "if the left operand is enclosed in parenthesis" is incorrect wording.

It is certainly true that not everything in Perl that is enclosed in parentheses is a list; suggesting that in this documentation would be misleading. Further explaining what parenthesized items are and are not lists\, and what non-parenthesized items are and are not lists\, should be redundant with other parts of the Perl documentation that explain the individual syntax elements.

The Perl user does need to understand the differences between arrays\, lists\, and expressions\, and how the context of an operator affects the interpretation of syntax.

'x' does seem to be somewhat unique in that its own context affects the context of its operands... can anyone give other examples of that?

Speaking of weird exceptions...

$ perl -wle '@​foo = ("a".."b"); $x = @​foo x 2; print $x' 22

$ perl -wle '@​foo = ("a".."b"); $x = (@​foo) x 2; print $x' 22

$ perl -wle '$x = ("a".."b") x 2; print $x' Argument "a" isn't numeric in range (or flip) at -e line 1. Use of uninitialized value in range (or flip) at -e line 1. Argument "b" isn't numeric in range (or flop) at -e line 1. Use of uninitialized value in range (or flop) at -e line 1. 1E01E0

$ perl -wle '$x = (("a".."b") x 2); print $x' Argument "a" isn't numeric in range (or flip) at -e line 1. Use of uninitialized value in range (or flip) at -e line 1. Argument "b" isn't numeric in range (or flop) at -e line 1. Use of uninitialized value in range (or flop) at -e line 1. 1E01E0

Which seems to be a special case of..

$ perl -wle 'print scalar (1..2)' Use of uninitialized value in range (or flip) at -e line 1.

And I'm not going to pretend I understand scalar flip/fop.

-- Glenn -- http​://nevcal.com/

A protocol is complete when there is nothing left to remove. -- Stuart Cheshire\, Apple Computer\, regarding Zero Configuration Networking

p5pRT commented 16 years ago

From @schwern

Glenn Linderman wrote​:

'x' does seem to be somewhat unique in that its own context affects the context of its operands... can anyone give other examples of that?

Hmm\, good point. I can't think of any offhand.

-- 44. I am not the atheist chaplain.   -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army   http​://skippyslist.com/list/

p5pRT commented 16 years ago

From blgl@hagernas.com

In article \48F4CD2B\.6050205@&#8203;NevCal\.com\, perl@​NevCal.com (Glenn Linderman) wrote​:

'x' does seem to be somewhat unique in that its own context affects the context of its operands... can anyone give other examples of that?

Unary​: + Binary​: && || // and or (right operand) Ternary​: ?​: (second and third operands)

/Bo Lindbergh

p5pRT commented 16 years ago

From Eirik-Berg.Hanssen@allverden.no

Bo Lindbergh \blgl@&#8203;hagernas\.com writes​:

In article \48F4CD2B\.6050205@&#8203;NevCal\.com\, perl@​NevCal.com (Glenn Linderman) wrote​:

'x' does seem to be somewhat unique in that its own context affects the context of its operands... can anyone give other examples of that?

Unary​: + Binary​: && || // and or (right operand) Ternary​: ?​: (second and third operands)

  Also\, comma. If comma in list context is considered an operator?

sub w { $w=wantarray; push @​w\, $w } @​x = (w\, w); # list\, list $x = (w\, w); # void\, scalar use Data​::Dumper; print Dumper(\@​w);

__END__

$VAR1 = [   1\,   1\,   undef\,   ''   ];

Eirik -- The basic facts are that the rate of decrease of the population growth rate has been falling for decades\, at an ever increasing rate.   --jsnead@​netcom.com (John R. Snead)

p5pRT commented 11 years ago

From @jkeenan

On Mon Oct 13 14​:11​:35 2008\, jschneid@​redhat.com wrote​:

This is a bug report for perl from jschneid@​redhat.com\,

generated with the help of perlbug 1.35 running under perl v5.8.8.

----------------------------------------------------------------- [Please enter your report here]

The 'x' operator forces scalar context on the left operand\, unless that operand is enclosed in parens\, even if the left operand is an array variable.

For example\, the following code fragment prints the string "22"\, rather than the expected four lines of alternating words​:

@​foo = qw(foo bar); print "$_\n" foreach @​foo x 2;

The alternative​:

print "$_\n" foreach qw(foo bar) x 2;

does print the alternating lines.

"perldoc perlop" is not clear on the expected behavior - quoting​:

In scalar context or if the left operand is not enclosed in parentheses\, it returns a string consisting of the left operand repeated the number of times specified by the right operand. In list context\, if the left operand is enclosed in parentheses or is a list formed by "qw/STRING/"\, it repeats the list.

It could be read that the behavior is the documented behavior\, but it certainly looks like wrong behavior. It also violates the principal of least surprise. Why should the "x" operator force a particular context on an operand that already has a perfectly good context of its own?

In the event this is not fixed\, I suggest the passage above be amended to​:

The "x" operator will evaluate its left operand in scalar context\, unless the left operand is enclosed in parentheses\, or is a list formed by "qw/STRING/"\, where it will be evaluated in list context. In scalar context\, it returns a string consisting of the left operand repeated the number of times specified by the right operand. In list context\, it repeats the list.

I reviewed this older ticket this evening. The OP was concerned about two different instances of the 'x' binary repetition operator. In the first case\, everything DWIMs​:

##### $ perl -E '@​foo = qw(foo bar);say $_ for (@​foo) x 2;' foo bar foo bar #####

Drop the parentheses around the '@​foo' and you get the second case​:

##### $ perl -E '@​foo = qw(foo bar);say $_ for @​foo x 2;' 22 #####

... which the OP felt violated the principle of least surprise\, even if it technically satisfied the documentation for the 'x' operator in 'perlop'. In blead\, that documentation reads​:

##### Binary "x" is the repetition operator. In scalar context or if the left operand is not enclosed in parentheses\, it returns a string consisting of the left operand repeated the number of times specified by the right operand. In list context\, if the left operand is enclosed in parentheses or is a list formed by C\<qw/STRING/>\, it repeats the list. If the right operand is zero or negative\, it returns an empty string or an empty list\, depending on the context. #####

I am attaching a patch in the same spirit as a revision suggested by the original poster. Please review.

Thank you very much. Jim Keenan

p5pRT commented 11 years ago

From @jkeenan

0001-Clarify-case-of-x-operator-with-left-operand-lacking.patch ```diff From bbd88daf10e3c66a615601e34a020bd10361b08c Mon Sep 17 00:00:00 2001 From: James E Keenan Date: Mon, 18 Feb 2013 21:51:19 -0500 Subject: [PATCH] Clarify case of "x" operator with left operand lacking parens. Modification of documentation change suggested by James Schneider. For: RT #59884. --- pod/perlop.pod | 33 +++++++++++++++++++-------------- 1 files changed, 19 insertions(+), 14 deletions(-) diff --git a/pod/perlop.pod b/pod/perlop.pod index 40402be..c1b1944 100644 --- a/pod/perlop.pod +++ b/pod/perlop.pod @@ -297,22 +297,27 @@ operator is not as well defined for negative operands, but it will execute faster. X<%> X X X -Binary "x" is the repetition operator. In scalar context or if the left -operand is not enclosed in parentheses, it returns a string consisting -of the left operand repeated the number of times specified by the right -operand. In list context, if the left operand is enclosed in -parentheses or is a list formed by C, it repeats the list. -If the right operand is zero or negative, it returns an empty string -or an empty list, depending on the context. +Binary "x" is the repetition operator. It will evaluate its left +operand in scalar context unless (a) the left operand is enclosed in +parentheses or (b) is a list formed by C -- in which case it +will evaluate its left operand in list context. In scalar context, it +returns a string consisting of the left operand repeated the number of +times specified by the right operand. In list context, it repeats the +list. X - print '-' x 80; # print row of dashes - - print "\t" x ($tab/8), ' ' x ($tab%8); # tab over - - @ones = (1) x 80; # a list of 80 1's - @ones = (5) x @ones; # set all elements to 5 - + print '-' x 80; # print row of dashes + print "\t" x ($tab/8), + ' ' x ($tab%8); # tab over + + @terms = ('foo', 'bar'); + print "$_\n" for @terms x 2; # prints "22\n"; lack of parens + # on left operand causes @terms + # to be evaluated in scalar context + + @ones = (1) x 80; # a list of 80 1's + @ones = (5) x @ones; # set all elements to 5 + @terms = qw/foo bar/ x 2; # ('foo', 'bar', 'foo', 'bar') =head2 Additive Operators X -- 1.6.3.2 ```
p5pRT commented 11 years ago

From @tamias

On Mon\, Feb 18\, 2013 at 06​:55​:34PM -0800\, James E Keenan via RT wrote​:

-Binary "x" is the repetition operator. In scalar context or if the left -operand is not enclosed in parentheses\, it returns a string consisting -of the left operand repeated the number of times specified by the right -operand. In list context\, if the left operand is enclosed in -parentheses or is a list formed by C\<qw/STRING/>\, it repeats the list. -If the right operand is zero or negative\, it returns an empty string -or an empty list\, depending on the context. +Binary "x" is the repetition operator. It will evaluate its left +operand in scalar context unless (a) the left operand is enclosed in +parentheses or (b) is a list formed by C\<qw/STRING/> -- in which case it +will evaluate its left operand in list context. In scalar context\, it +returns a string consisting of the left operand repeated the number of +times specified by the right operand. In list context\, it repeats the +list.

The original text is precise and correct\, while the proposed text conflates the context of the operator with the context of the left operand.

If the 'x' operator is in scalar context\, then the left operand is evaluated in scalar context and the result is a string.

If the 'x' operator is in list context *and* the left operand is enclosed in parentheses or is a qw// list\, then the left operand is evaluated in list context and the result is a list.

Ronald

p5pRT commented 11 years ago

From tchrist@perl.com

"James E Keenan via RT" \perlbug\-followup@&#8203;perl\.org wrote   on Mon\, 18 Feb 2013 18​:55​:34 PST​:

I reviewed this older ticket this evening. The OP was concerned about two different instances of the 'x' binary repetition operator. In the first case\, everything DWIMs​:

##### $ perl -E '@​foo = qw(foo bar);say $_ for (@​foo) x 2;' foo bar foo bar #####

Drop the parentheses around the '@​foo' and you get the second case​:

##### $ perl -E '@​foo = qw(foo bar);say $_ for @​foo x 2;' 22 #####

... which the OP felt violated the principle of least surprise\, even if it technically satisfied the documentation for the 'x' operator in 'perlop'. In blead\, that documentation reads​:

##### Binary "x" is the repetition operator. In scalar context or if the left operand is not enclosed in parentheses\, it returns a string consisting of the left operand repeated the number of times specified by the right operand. In list context\, if the left operand is enclosed in parentheses or is a list formed by C\<qw/STRING/>\, it repeats the list. If the right operand is zero or negative\, it returns an empty string or an empty list\, depending on the context. #####

I am attaching a patch in the same spirit as a revision suggested by the original poster. Please review.

The doc patch looks good. Thanks.

I agree with the original submitter that this is all somewhat bizarre\, but it exists for historical reasons. The weirdness was originally introduced so as not to break existing code. It persists now\, rather more than twenty years later\, for the same reason\, but this time the amount of code out there is surely many orders of magnitude greater.

I doubt if we had it to do over again\, we would do it this way.

--tom

p5pRT commented 11 years ago

From @jkeenan

On Mon Feb 18 19​:43​:03 2013\, tom christiansen wrote​:

"James E Keenan via RT" \perlbug\-followup@&#8203;perl\.org wrote on Mon\, 18 Feb 2013 18​:55​:34 PST​:

I reviewed this older ticket this evening. The OP was concerned about two different instances of the 'x' binary repetition operator. In the first case\, everything DWIMs​:

##### $ perl -E '@​foo = qw(foo bar);say $_ for (@​foo) x 2;' foo bar foo bar #####

Drop the parentheses around the '@​foo' and you get the second case​:

##### $ perl -E '@​foo = qw(foo bar);say $_ for @​foo x 2;' 22 #####

... which the OP felt violated the principle of least surprise\, even if it technically satisfied the documentation for the 'x' operator in 'perlop'. In blead\, that documentation reads​:

##### Binary "x" is the repetition operator. In scalar context or if the left operand is not enclosed in parentheses\, it returns a string consisting of the left operand repeated the number of times specified by the right operand. In list context\, if the left operand is enclosed in parentheses or is a list formed by C\<qw/STRING/>\, it repeats the list. If the right operand is zero or negative\, it returns an empty string or an empty list\, depending on the context. #####

I am attaching a patch in the same spirit as a revision suggested by the original poster. Please review.

The doc patch looks good. Thanks.

We had one vote for the patch (tomc) and one against (ronald). Hence\, I held off on applying it. Anyone else want to sound off?

Thank you very much. Jim Keenan

p5pRT commented 11 years ago

From @bulk88

On Tue Mar 12 18​:21​:40 2013\, jkeenan wrote​:

On Mon Feb 18 19​:43​:03 2013\, tom christiansen wrote​:

"James E Keenan via RT" \perlbug\-followup@&#8203;perl\.org wrote on Mon\, 18 Feb 2013 18​:55​:34 PST​:

I reviewed this older ticket this evening. The OP was concerned about two different instances of the 'x' binary repetition operator. In the first case\, everything DWIMs​:

##### $ perl -E '@​foo = qw(foo bar);say $_ for (@​foo) x 2;' foo bar foo bar #####

Drop the parentheses around the '@​foo' and you get the second case​:

##### $ perl -E '@​foo = qw(foo bar);say $_ for @​foo x 2;' 22 #####

... which the OP felt violated the principle of least surprise\, even if it technically satisfied the documentation for the 'x' operator in 'perlop'. In blead\, that documentation reads​:

##### Binary "x" is the repetition operator. In scalar context or if the left operand is not enclosed in parentheses\, it returns a string consisting of the left operand repeated the number of times specified by the right operand. In list context\, if the left operand is enclosed in parentheses or is a list formed by C\<qw/STRING/>\, it repeats the list. If the right operand is zero or negative\, it returns an empty string or an empty list\, depending on the context. #####

I am attaching a patch in the same spirit as a revision suggested by the original poster. Please review.

The doc patch looks good. Thanks.

We had one vote for the patch (tomc) and one against (ronald). Hence\, I held off on applying it. Anyone else want to sound off?

Thank you very much. Jim Keenan

I like the current blead wording more. -- bulk88 ~ bulk88 at hotmail.com

p5pRT commented 11 years ago

From @rjbs

* James E Keenan via RT \perlbug\-followup@&#8203;perl\.org [2013-03-12T21​:21​:40]

We had one vote for the patch (tomc) and one against (ronald). Hence\, I held off on applying it. Anyone else want to sound off?

I agree with Ronald's criticism.

-- rjbs

p5pRT commented 11 years ago

From @jkeenan

On Wed Mar 13 06​:23​:09 2013\, perl.p5p@​rjbs.manxome.org wrote​:

* James E Keenan via RT \perlbug\-followup@&#8203;perl\.org [2013-03-12T21​:21​:40]

We had one vote for the patch (tomc) and one against (ronald). Hence\, I held off on applying it. Anyone else want to sound off?

I agree with Ronald's criticism.

Marking as rejected. Thank you very much.

Jim Keenan

p5pRT commented 11 years ago

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