Precedence of qw
eff_i_g
created: 2006-04-04 12:21:49
use strict;ers,

I am pushing two identical strings onto an array. The code below shows what works and what doesn't. Why does qw() need to be surrounded by parens? I'm not sure what it is classified as, or where it appears in the line of precedence, etc. I thought qw() provided its own list context, as demonstrated by "my $scalar = qw(A B C); print $scalar;", which yields 3.

Thanks.
#!/usr/bin/perl -w
use strict;

my @array;

### works
push @array, ('X') x 2;
print @array, "\n";

### doesn't work - x is bareword?
#push @array, qw(X) x 2;
#print @array, "\n";

### works
push @array, (qw(X)) x 2;
print @array, "\n";

### works
push @array, +(qw(X)) x 2;
print @array, "\n";
Re: Precedence of qw
created: 2006-04-04 12:30:46

x doesn't play by normal rules and will do things slightly funny just because the qw() used parens instead of some other delimiter. So x's special handling are higher priority just because it's special. You shouldn't infer much from it. This is likely all very implementation specific too so it could change.

⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re^2: Precedence of qw
created: 2006-04-04 12:36:10

I get the same behaviour with other delimiters.

@array = qw!X! x 2;
print @array, "\n";

gives

Unquoted string "x" may clash with future reserved word at 541179.pl line 3.
Number found where operator expected at 541179.pl line 3, near "x 2"
        (Do you need to predeclare x?)
syntax error at 541179.pl line 3, near "qw!X! x "
Execution of 541179.pl aborted due to compilation errors.
Re: Precedence of qw
created: 2006-04-04 12:33:22

You implied the problem is related to use strict, but it isn't:

@array = qw(X) x 2;
print @array, "\n";

gives

Unquoted string "x" may clash with future reserved word at script.pl line 4.
Number found where operator expected at 541178.pl line 4, near "x 2"
        (Do you need to predeclare x?)
syntax error at 541178.pl line 4, near "qw(X) x "
Execution of 541178.pl aborted due to compilation errors.

I've noticed this bug before.

Re^2: Precedence of qw
created: 2006-04-04 12:58:06
Sorry about that; it wasn't my intent.

I noticed something else that I posted. This:
#!/usr/bin/perl -w
use strict;

my $scalar = qw(A B C);
print $scalar, "\n";
Gives:
Use of implicit split to @_ is deprecated at ./test27.pl line 4.
3

And perldiag has:
Use of implicit split to @_ is deprecated
(D deprecated) It makes a lot of work for the compiler when you clobber a subroutine's argument list, so it's better if you assign the results of a split() explicitly to an array (or list).

I'm not sure how these are related...
Re^3: Precedence of qw
created: 2006-04-04 13:02:58

What version of perl are you using? Mine doesn't say that at all.

Re^4: Precedence of qw
created: 2006-04-04 13:06:36
duff, version 5.005_03 built for sun4-solaris. We have other versions on other machines; I'll try those out.
Re^5: Precedence of qw
created: 2006-04-04 13:38:36

Perp prior to 5.6 implemented qw() as a split() to be executed at runtime.

⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re^3: Precedence of qw
created: 2006-04-04 13:07:52

Quote split:

In scalar context, returns the number of fields found and splits into the @_ array. Use of split in scalar context is deprecated, however, because it clobbers your subroutine arguments.

Your version of Perl probably implements qw(A B C) as split('', q(A B C)). If you want the count, use my $scalar = () = qw(A B C);.

I say "your version", because perl 5.6.1 gives

Useless use of a constant in void context at 541192.pl line 4.
Useless use of a constant in void context at 541192.pl line 4.
C
Re^4: Precedence of qw
created: 2006-04-04 13:39:15

The split is performed at runtime for perl prior to 5.6..

⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re^3: Precedence of qw
created: 2006-04-04 17:37:52
$ perl -w
use strict;

my $scalar = qw(A B C);
Useless use of a constant in void context at - line 3.
Useless use of a constant in void context at - line 3.
print $scalar, "\n";
C
$ perl -v

This is perl, v5.8.7 built for cygwin-thread-multi-64int
(with 1 registered patch, see perl -V for more detail)
By the way, this has nothing to do with qw.
$ perl -w
my $scalar = (1, 2, 3);
Useless use of a constant in void context at - line 1.
Re: Precedence of qw
created: 2006-04-04 13:03:42
seems like you are getting too complicated and choosing the wrong operator here. Tell me why you want to use the qw operator?
from perldoc perlop

qw/STRING/ Evaluates to a list of the words extracted out of STRING, using embedded whitespace as the word delimiters. It can be under- stood as being roughly equivalent to: split(’ ’, q/STRING/); the differences being that it generates a real list at compile time, and in scalar context it returns the last element in the list.

So why in the heck would you use this operator on one value in the middle of a push statement. The interpreter does its best but you are making it hemmorage here. use the q operator.

#This works:

push @array, q(X) x 2;
print @array, "\n";

Re^2: Precedence of qw
created: 2006-04-04 13:14:01
doc,

I was looking at qw() for maintenance purposes; so some one would be able to type in a new word if need be instead of the extra comma, quote, quote--Yes, picky, I know. But, again, this is used a lot in Perl to allow for easy modification.

Your code will not work because q(X) x 2 results in ('XX') not ('X', 'X') as you can see via:
#!/usr/bin/perl -w
use strict;
my @array;
push @array, q(X) x 2;
print join ' - ', @array, "\n";
@array = ();
push @array, ('X') x 2;
print join ' - ', @array, "\n";
Re^3: Precedence of qw
created: 2006-04-04 13:39:26
(q(X)) x 2 would give ('X', 'X')
Re^3: Precedence of qw
created: 2006-04-04 22:51:21
aha. I see. thanks.
although if you are using single words? I can see the need for a list context with a list of things.

anyhoo, glad the fix is in release, and my compliments to you for a clever username. one of the more clever ones on perlmonks.
Re: Precedence of qw
created: 2006-04-04 15:12:00
This was fixed in perl 5.8.8:

$ perl587 -wle 'print for qw(X Y) x 2'
Unquoted string "x" may clash with future reserved word at -e line 1.
Number found where operator expected at -e line 1, near "x 2"
        (Do you need to predeclare x?)
syntax error at -e line 1, near "qw(X Y) x "
Execution of -e aborted due to compilation errors.

$ perl588 -wle 'print for qw(X Y) x 2'
X
Y
X
Y
$

Dave.

Re^2: Precedence of qw
created: 2006-04-04 15:25:08

Indeed! Quote perl588delta:

You can now use the x operator to repeat a qw// list. This used to raise a syntax error.
Re^2: Precedence of qw
created: 2006-04-04 15:46:21
Thanks a bunch!

perlmonks.org content © perlmonks.org and codeacrobat, dave_the_m, diotalevi, doc_faustroll, duff, eff_i_g, ikegami

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03