[Edinburgh-pm] Ingorance
Aaron Crane
perl at aaroncrane.co.uk
Wed Mar 7 07:40:02 PST 2007
Andrew Smith writes:
> I was playing around with the attached test program and don't
> understand why line 8 doesn't prints *"1* rather *"1 2 3"* for the
> value $words[1], and just *2* for $words1[2] rather than *def*.
> as it does when printing the full array. I think I understand that *qw*
> puts single *'* around space delimited words which is why the double *"*
> get included in element 1.
Perl's C<qw> is actually implemented with C<split> on the inside. You
can imagine that the compiler replaces every suitable occurrence of the
two letters "q" and "w" with this piece of text:
split ' ', q
That is:
qw/abc def ghi/
# will turn into:
split ' ', q/abc def ghi/
Since C< q/abc def ghi/ > is the same as C< 'abc def ghi' >, that means
that the result of the split is the same as C< ('abc', 'def', 'ghi') >.
The splitting happens at compile time, so there's no run-time penalty
for using C<qw> rather than any other literal list. But there really is
an actual call to C<split> happening inside Perl when you use a C<qw>.
Imagining that C<qw> inserts C<'> where needed isn't going to be
productive.
Similarly:
qw/abc "1 2 3" def/
# will turn into:
split ' ', q/abc "1 2 3" def/;
So the thing being split is C< q/abc "1 2 3" def/ >; when that gets
split on whitespace, the result is the same as this list:
('abc', '"1', '2', '3"', 'def')
That should explain why you get the behaviour you do with this bit of
your code:
my @words1=qw/abc "1 2 3" def/;
print join(":", at words1), "\n";
print $words1[1],"\n",$words1[2],"\n";
That is, because the C< qw/.../ > has 4 chunks of whitespace, @words1
has 5 elements. The first C<print> prints all five out, with colons
between; the second prints out the second and third elements on lines of
their own. (Not the first and second, because array indexing is
0-based.)
As for the other chunk of code:
my @words2=("abc","1 2 3","def");
print join(":", at words2), "\n";
print $words2[1],"\n",$words2[2],"\n";
The @words2 array is initialized with the three elements of the list you
give it, each of which is a string:
"abc" # $words2[0]
"1 2 3" # $words2[1]
"def" # $words2[2]
The quotes there are part of the syntax for literal strings, not part of
the data in the strings themselves.
So printing out all the elements of @words2, joined with a colon, produces
abc:1 2 3:def
because you're not doing anything that could split $words2[1] on
whitespace.
--
Aaron Crane
More information about the Edinburgh-pm
mailing list