Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qw and x operators doesn't mix #7919

Closed
p5pRT opened this issue May 19, 2005 · 16 comments
Closed

qw and x operators doesn't mix #7919

p5pRT opened this issue May 19, 2005 · 16 comments

Comments

@p5pRT
Copy link

p5pRT commented May 19, 2005

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

Searchable as RT35885$

@p5pRT
Copy link
Author

p5pRT commented May 19, 2005

From @salva

Created by @salva

for instance

  $ perl -e 'print qw|foo bar| x 3'
  Number found where operator expected at -e line 1, near "x 3"
  (Do you need to predeclare x?)
  syntax error at -e line 1, near "qw|foo bar| x "
  Execution of -e aborted due to compilation errors.

while

  $ perl -e '$,="-"; print ((qw|foo bar|) x 3)'
  foo-bar-foo-bar-foo-bar

produces the desired behaviour

Cheers

  - Salvador.

Perl Info

Flags:
    category=core
    severity=wishlist

Site configuration information for perl v5.8.4:

Configured by Debian Project at Tue Mar  8 20:31:23 EST 2005.

Summary of my perl5 (revision 5 version 8 subversion 4) configuration:
  Platform:
    osname=linux, osvers=2.4.27-ti1211, archname=i386-linux-thread-multi
    uname='linux kosh 2.4.27-ti1211 #1 sun sep 19 18:17:45 est 2004 i686 gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i386-linux -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.4 -Dsitearch=/usr/local/lib/perl/5.8.4 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.4 -Dd_dosuid -des'
    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='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -I/usr/local/include'
    ccversion='', gccversion='3.3.5 (Debian 1:3.3.5-9)', 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='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=/lib/libc-2.3.2.so, so=so, useshrplib=true, libperl=libperl.so.5.8.4
    gnulibc_version='2.3.2'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    


@INC for perl v5.8.4:
    /etc/perl
    /usr/local/lib/perl/5.8.4
    /usr/local/share/perl/5.8.4
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.8
    /usr/share/perl/5.8
    /usr/local/lib/site_perl
    .


Environment for perl v5.8.4:
    HOME=/home/salva
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=~/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented May 19, 2005

From @salva

Created by @salva

for instance​:

  $ perl -e '@​foo = qw(foo bar) x 3'
  Number found where operator expected at -e line 1, near "x 3"
  (Do you need to predeclare x?)
  syntax error at -e line 1, near "qw(foo bar) x "
  Execution of -e aborted due to compilation errors.

I would expect 'qw(foo bar) x 3' to behave as '(qw(foo bar)) x 3'

Cheers,

  - Salvador.

Perl Info

Flags:
    category=core
    severity=wishlist

Site configuration information for perl v5.8.4:

Configured by Debian Project at Tue Mar  8 20:31:23 EST 2005.

Summary of my perl5 (revision 5 version 8 subversion 4)
configuration:
  Platform:
    osname=linux, osvers=2.4.27-ti1211,
archname=i386-linux-thread-multi
    uname='linux kosh 2.4.27-ti1211 #1 sun sep 19 18:17:45 est 2004
i686 gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN
-Dcccdlflags=-fPIC -Darchname=i386-linux -Dprefix=/usr
-Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8
-Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5
-Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local
-Dsitelib=/usr/local/share/perl/5.8.4
-Dsitearch=/usr/local/lib/perl/5.8.4 -Dman1dir=/usr/share/man/man1
-Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1
-Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl
-Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm
-Duseshrplib -Dlibperl=libperl.so.5.8.4 -Dd_dosuid -des'
    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='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS
-DDEBIAN -fno-strict-aliasing -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN
-fno-strict-aliasing -I/usr/local/include'
    ccversion='', gccversion='3.3.5 (Debian 1:3.3.5-9)',
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='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=/lib/libc-2.3.2.so, so=so, useshrplib=true,
libperl=libperl.so.5.8.4
    gnulibc_version='2.3.2'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    


@INC for perl v5.8.4:
    /etc/perl
    /usr/local/lib/perl/5.8.4
    /usr/local/share/perl/5.8.4
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.8
    /usr/share/perl/5.8
    /usr/local/lib/site_perl
    .


Environment for perl v5.8.4:
    HOME=/home/salva
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=~/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
    PERL_BADLANG (unset)
    SHELL=/bin/bash



		
__________________________________ 
Yahoo! Mail Mobile 
Take Yahoo! Mail with you! Check email on your mobile phone. 
http://mobile.yahoo.com/learn/mail 

@p5pRT
Copy link
Author

p5pRT commented May 19, 2005

From @ysth

On Thu, May 19, 2005 at 04​:12​:45PM -0000, Salvador FandiÃ�Â�Ã�±o wrote​:

for instance​:

$ perl -e '@​foo = qw(foo bar) x 3'
Number found where operator expected at -e line 1, near "x 3"
(Do you need to predeclare x?)
syntax error at -e line 1, near "qw(foo bar) x "
Execution of -e aborted due to compilation errors.

I would expect 'qw(foo bar) x 3' to behave as '(qw(foo bar)) x 3'

perlop says​:

  In list context, if the left operand is enclosed in
  parentheses, it repeats the list.

I would rather not add qw to that as an additional special case;
instead qw(foo bar) x 3 should behave as scalar(qw(foo bar)) x 3,
generating a single string "barbarbar" (and a warning "Useless use of
a constant in void context").

To get qw/foo bar foo bar foo bar/, just enclose the qw// in parentheses​:
(qw/foo bar/ x 3).

@p5pRT
Copy link
Author

p5pRT commented May 19, 2005

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

@p5pRT
Copy link
Author

p5pRT commented May 20, 2005

From @salva

--- Yitzchak Scott-Thoennes via RT <perlbug-followup@​perl.org> wrote​:

To get qw/foo bar foo bar foo bar/, just enclose the qw// in
parentheses​:
(qw/foo bar/ x 3).

that doesn't work either, did you meant...

  (qw/foo bar/) x 3

?

cheers,

  - Salvador

 
__________________________________
Yahoo! Mail Mobile
Take Yahoo! Mail with you! Check email on your mobile phone.
http​://mobile.yahoo.com/learn/mail

@p5pRT
Copy link
Author

p5pRT commented May 20, 2005

From @ysth

On Thu, May 19, 2005 at 11​:13​:44PM -0700, Salvador Fandiño wrote​:

--- Yitzchak Scott-Thoennes wrote​:

To get qw/foo bar foo bar foo bar/, just enclose the qw// in
parentheses​:
(qw/foo bar/ x 3).

that doesn't work either, did you meant...

(qw/foo bar/) x 3

Oops. Yes.

@p5pRT
Copy link
Author

p5pRT commented May 20, 2005

From @rgs

Yitzchak Scott-Thoennes wrote​:

On Thu, May 19, 2005 at 04​:12​:45PM -0000, Salvador Fandiño wrote​:

for instance​:

$ perl -e '@​foo = qw(foo bar) x 3'
Number found where operator expected at -e line 1, near "x 3"
(Do you need to predeclare x?)
syntax error at -e line 1, near "qw(foo bar) x "
Execution of -e aborted due to compilation errors.

I would expect 'qw(foo bar) x 3' to behave as '(qw(foo bar)) x 3'

perlop says​:

In list context, if the left operand is enclosed in
parentheses, it repeats the list.

I would rather not add qw to that as an additional special case;
instead qw(foo bar) x 3 should behave as scalar(qw(foo bar)) x 3,
generating a single string "barbarbar" (and a warning "Useless use of
a constant in void context").

There's indeed a bug, since the tokenizer doesn't set its state
after parsing qw/..../. Fixed by this nit :

--- toke.c (revision 4822)
+++ toke.c (working copy)
@​@​ -4956,6 +4956,7 @​@​
  s = scan_str(s,FALSE,FALSE);
  if (!s)
  missingterm((char*)0);
+ PL_expect = XOPERATOR;
  force_next(')');
  if (SvCUR(PL_lex_stuff)) {
  OP *words = Nullop;
End

But... technically I agree with Yitzchak on the exegesis of perlop,
qw() has a strong "list" feeling. Moreover, perl 6 seems to agree :

$ ./pugs -e 'say for qw(foo bar) xx 2'
foo
bar
foo
bar

(asking on #perl6 confirms this.)
And Perl 5 hasn't a strong history of not introducing special parsing
cases. So I'll think I'll made it work like this :

$ bleadperl -le 'print for qw(foo bar) x 2'
foo
bar
foo
bar

@p5pRT
Copy link
Author

p5pRT commented May 20, 2005

From @ysth

On Fri, May 20, 2005 at 11​:07​:25AM +0200, Rafael Garcia-Suarez wrote​:

Yitzchak Scott-Thoennes wrote​:

On Thu, May 19, 2005 at 04​:12​:45PM -0000, Salvador Fandi??o wrote​:

for instance​:

$ perl -e '@​foo = qw(foo bar) x 3'
Number found where operator expected at -e line 1, near "x 3"
(Do you need to predeclare x?)
syntax error at -e line 1, near "qw(foo bar) x "
Execution of -e aborted due to compilation errors.

I would expect 'qw(foo bar) x 3' to behave as '(qw(foo bar)) x 3'

perlop says​:

In list context, if the left operand is enclosed in
parentheses, it repeats the list.

I would rather not add qw to that as an additional special case;
instead qw(foo bar) x 3 should behave as scalar(qw(foo bar)) x 3,
generating a single string "barbarbar" (and a warning "Useless use of
a constant in void context").

There's indeed a bug, since the tokenizer doesn't set its state
after parsing qw/..../. Fixed by this nit :

--- toke.c (revision 4822)
+++ toke.c (working copy)
@​@​ -4956,6 +4956,7 @​@​
s = scan_str(s,FALSE,FALSE);
if (!s)
missingterm((char*)0);
+ PL_expect = XOPERATOR;
force_next(')');
if (SvCUR(PL_lex_stuff)) {
OP *words = Nullop;
End

But... technically I agree with Yitzchak on the exegesis of perlop,
qw() has a strong "list" feeling. Moreover, perl 6 seems to agree :

$ ./pugs -e 'say for qw(foo bar) xx 2'
foo
bar
foo
bar

(asking on #perl6 confirms this.)
And Perl 5 hasn't a strong history of not introducing special parsing
cases. So I'll think I'll made it work like this :

$ bleadperl -le 'print for qw(foo bar) x 2'
foo
bar
foo
bar

That's the opposite of what I was trying to say. I think of ()x and x
as being two separate operators, that happen to behave the same in
scalar context. I don't think the list form should apply if there aren't
explict parens around the left operand.

@p5pRT
Copy link
Author

p5pRT commented May 20, 2005

From @rgs

Yitzchak Scott-Thoennes wrote​:

$ bleadperl -le 'print for qw(foo bar) x 2'
foo
bar
foo
bar

That's the opposite of what I was trying to say.

Yes, I'm quite aware of this :) A "nonetheless" is missing in my
previous mail.

I think of ()x and x
as being two separate operators, that happen to behave the same in
scalar context. I don't think the list form should apply if there aren't
explict parens around the left operand.

Yes... but from a DWIM point of view I think that people are used to
assume () around qw lists; or to see qw just as another form of lists.
And (qw(foo bar)) is just clutter, since qw(foo bar) x 3 is not going to
be used usefully.

Perl 6 works around this difficulty by having separate x and xx
operators.

@p5pRT
Copy link
Author

p5pRT commented May 20, 2005

From @ysth

On Fri, May 20, 2005 at 11​:07​:25AM +0200, Rafael Garcia-Suarez wrote​:

qw() has a strong "list" feeling. Moreover, perl 6 seems to agree :

$ ./pugs -e 'say for qw(foo bar) xx 2'
foo
bar
foo
bar

Is p6's xx supposed to have both roles of p5's x?

It sure seems to work differently; I'm told that this​:

./pugs -e 'sub foo { ("foo","bar") } say for foo() xx 2'

produces
foo
bar
foo
bar

also, while for perl5, we have​:

$ ./perl -le'sub foo { ("foo","bar") } print for foo() x 2'
barbar

@p5pRT
Copy link
Author

p5pRT commented May 20, 2005

From @demerphq

On 5/20/05, Rafael Garcia-Suarez <rgarciasuarez@​mandriva.com> wrote​:

Yitzchak Scott-Thoennes wrote​:

$ bleadperl -le 'print for qw(foo bar) x 2'
foo
bar
foo
bar

That's the opposite of what I was trying to say.

Yes, I'm quite aware of this :) A "nonetheless" is missing in my
previous mail.

I think of ()x and x
as being two separate operators, that happen to behave the same in
scalar context. I don't think the list form should apply if there aren't
explict parens around the left operand.

Yes... but from a DWIM point of view I think that people are used to
assume () around qw lists; or to see qw just as another form of lists.
And (qw(foo bar)) is just clutter, since qw(foo bar) x 3 is not going to
be used usefully.

theres precedence for this interpretation as well​:

D​:\dev>perl -wle "use strict; for my $x qw(foo bar baz) { print $x }"
foo
bar
baz

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

@p5pRT
Copy link
Author

p5pRT commented May 20, 2005

From @rgs

Yitzchak Scott-Thoennes wrote​:

On Fri, May 20, 2005 at 11​:07​:25AM +0200, Rafael Garcia-Suarez wrote​:

qw() has a strong "list" feeling. Moreover, perl 6 seems to agree :

$ ./pugs -e 'say for qw(foo bar) xx 2'
foo
bar
foo
bar

Is p6's xx supposed to have both roles of p5's x?

No; as Synopsis 03 says :

  x splits into two operators​: x (which concatenates repetitions of a
  string to produce a single string), and xx (which creates a list of
  repetitions of a list or scalar).

It sure seems to work differently; I'm told that this​:

./pugs -e 'sub foo { ("foo","bar") } say for foo() xx 2'

produces
foo
bar
foo
bar

also, while for perl5, we have​:

$ ./perl -le'sub foo { ("foo","bar") } print for foo() x 2'
barbar

I don't see the point... My point was that qw() forces immediate list
context on x; not that it forces list context on function return. (i.e.
that qw(foo bar) is more like ("foo","bar") than like "foo","bar".)

@p5pRT
Copy link
Author

p5pRT commented May 24, 2005

From @rgs

Rafael Garcia-Suarez wrote​:

There's indeed a bug, since the tokenizer doesn't set its state
after parsing qw/..../. Fixed by this nit :

--- toke.c (revision 4822)
+++ toke.c (working copy)
@​@​ -4956,6 +4956,7 @​@​
s = scan_str(s,FALSE,FALSE);
if (!s)
missingterm((char*)0);
+ PL_expect = XOPERATOR;
force_next(')');
if (SvCUR(PL_lex_stuff)) {
OP *words = Nullop;
End

I applied this as change 24560 to bleadperl, with a regression test that
says :

is( (join ',', (qw(a b c) x 3)), 'a,b,c,a,b,c,a,b,c', 'x on qw produces list' );

--
The universe (which others call the Library) is composed of an indefinite and
perhaps infinite number of hexagonal galleries.
  -- Borges

@p5pRT p5pRT closed this as completed May 24, 2005
@p5pRT
Copy link
Author

p5pRT commented May 24, 2005

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

@p5pRT
Copy link
Author

p5pRT commented May 24, 2005

From @ysth

On Tue, May 24, 2005 at 01​:51​:52PM +0200, Rafael Garcia-Suarez wrote​:

Rafael Garcia-Suarez wrote​:

There's indeed a bug, since the tokenizer doesn't set its state
after parsing qw/..../. Fixed by this nit :

--- toke.c (revision 4822)
+++ toke.c (working copy)
@​@​ -4956,6 +4956,7 @​@​
s = scan_str(s,FALSE,FALSE);
if (!s)
missingterm((char*)0);
+ PL_expect = XOPERATOR;
force_next(')');
if (SvCUR(PL_lex_stuff)) {
OP *words = Nullop;
End

I applied this as change 24560 to bleadperl, with a regression test that
says :

is( (join ',', (qw(a b c) x 3)), 'a,b,c,a,b,c,a,b,c', 'x on qw produces list' );

Inline Patch
--- perl/pod/perlop.pod.orig    2005-05-10 08:07:42.000000000 -0700
+++ perl/pod/perlop.pod 2005-05-24 08:50:05.524456000 -0700
@@ -250,9 +250,9 @@
 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, 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.
+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.
 
     print '-' x 80;            # print row of dashes
 
End of Patch.

@p5pRT
Copy link
Author

p5pRT commented May 24, 2005

From @rgs

Yitzchak Scott-Thoennes wrote​:

I applied this as change 24560 to bleadperl, with a regression test that
says :

is( (join ',', (qw(a b c) x 3)), 'a,b,c,a,b,c,a,b,c', 'x on qw produces list' );

--- perl/pod/perlop.pod.orig 2005-05-10 08​:07​:42.000000000 -0700
+++ perl/pod/perlop.pod 2005-05-24 08​:50​:05.524456000 -0700
@​@​ -250,9 +250,9 @​@​
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, 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.
+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.

Right; thanks, applied as change #24567.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant