问题
Please could you explain this apparently inconsistent behaviour to me:
use strict;
my @a;
print "a" x 2; # this prints: aa
@a = "a" x 2; print @a; # this prints: aa
print ("a") x 2; # this prints: a
@a = ("a") x 2; print @a; # this prints: aa
Shouldn't the last one print a single 'a'?
Edit: Ok so now this is kind of making more sense to me: "Binary "x" is the repetition operator...In list context, if the left operand is enclosed in parentheses or is a list formed by qw/STRING/, it repeats the list." perlop
This is as clear as mud to me (binary x - why use the word binary? Is there a denary X?) But anyway: @a = ("a") x 2 # seems to be in list context, in that we have an array at the beginning - an array is not a list, but it contains a list, so I think we probably have a list context, (not an array context although they might be synonymous).
i suppose the "left operand" is ("a"). (It's either that or @a). perlop doesn't say what an operand actually is, querying perldoc.perl.org gives "No matches found", and googling gives "In computer programming, an operand is a term used to describe any object that is capable of being manipulated." Like an array for instance.
So the left operand might be enclosed in brackets so maybe it should "repeat the list". The list is either: ("a") x 2
or it is: ("a")
If we repeated ("a") x 2
we would get ("a") x 2 ("a") x 2
. This doesn't seem right.
If we type: print $a[1]
we will get a single 'a', so "it repeats the list" means Perl turns ("a") x 2
into ("a", "a")
so we effectively get @a=("a", "a")
However, print ("a") x 2
does not get turned into ("a", "a")
. That's because print is a "list operator" with a high precedence. So there we effectively get: (print ("a")) x 2
An array is a term so it also has a high precedence, but @a=stuff involves the assignation operator = which has a relatively low precedence. So it's quite different from print.
回答1:
You are being bitten by a common Perl parsing gotcha. Your third statement print ("a") x 2
is parsed as:
(print ("a")) x 2;
You can add another set of parentheses to fix the parsing:
print (("a") x 2); # prints aa
回答2:
add use warnings;
in your script, then you will get warnings like
print (...) interpreted as function .
Useless use of repeat (x) in void context .
Do it like print (("a") x 2);
# this prints: aa
As you mentioned in comments, how to format your code, i would say see Perltidy.
Perltidy is a Perl script which indents and reformats Perl scripts to make them easier to read. If you write Perl scripts, or spend much time reading them, you will probably find it useful.
Some more information about Perltidy:
You can download perltidy and run it with its defaults, or customise it to use your preferred bracing style, indentation width etc.
Customisation is easy and there are a huge number of options. The defaults are usually a fine starting place.
Perltidy can also be used to generate colourised HTML output of your code.
Perltidy comes with a sensible set of defaults; but they may not be right for you. Fortunately you can use tidyview as a graphical user interface to preview perltidy’s changes to your code and see which options suit you best. You can download tidyview from CPAN.
Note: Always add use strict
and use warnings
at the begining of your scripts.
回答3:
I think the reason that you are getting strange behavior is because the print
command for perl is to expect a list. Quoting from the relevant documentation:
Also be careful not to follow the print keyword with a left parenthesis unless you want the corresponding right parenthesis to terminate the arguments to the print; put parentheses around all the arguments.
Putting parentheses makes it act like a function. Consider if you perform this test case:
x("y") x 2;
sub x {
my $y = shift;
print "1: $y\n"; #result 1: y
my $y = shift;
print "2: $y\n"; #result 2:
}
When written as a function call, your results are consistent for a function being evaluated to its arguments rather than an assignment being evaluated after the following operations.
来源:https://stackoverflow.com/questions/5055519/question-about-precedence-repetition-modifer