Why two `{` is required here?
$text =~ s/(cat|tomatoes)/ ${{ qw<tomatoes cat cat tomatoes> }}{$1} /ge;
And I can't replace ${{ qw<tomatoes cat cat tomatoes> }}{$1}
with { qw<tomatoes cat cat tomatoes> }->{$1}
,why?
UPDATE
5 @array = qw<a b c d>;
6 $ref = \@array;
7 @{$ref} = qw<1 2 3 4>;
8 #@$ref = qw<1 2 开发者_运维问答3 4>;//also works
9 print "@array";
So it indicates neither {}
nor ${}
is required to dereferencing,the {}
is only required when ambiguity arises,and $
only in scalar context.
${{ qw<tomatoes cat cat tomatoes> }}{$1}
is
my $ref = { qw<tomatoes cat cat tomatoes> };
${ $ref }{$key}
The inner brackets form an anonymous hash constructor. It creates a hash, assigns the contents of the brackets to it, then returns a reference to it.
The outer brackets are part of the hash dereference. They can be omitted (e.g. $$ref{$key}
instead of ${$ref}{$key}
) when unambiguous (e.g. when dereferencing a simple scalar), but this is not such a circumstance.
One can also dereference using the arrow notation, so one could also have used
{ qw<tomatoes cat cat tomatoes> }->{$1}
The difference is that the version being used is simply a variable lookup, so it doesn't require /e, while the latter is Perl code, so it does require /e.
If you had just
${ qw<tomatoes cat cat tomatoes> }{$1}
that would be the same as
${ "tomatoes" }{$1}
since qw() in scalar context returns the last value. That, in turn, is the same as
$tomatoes{$1}
(except that use strict;
wouldn't allow it) and that's obviously not what you want.
The outer brackets dereference the anonymous hash created by the inner brackets.
Update for clarification: The second format you use would work if you give the compiler a clue by putting a + in front of it:
+{ qw<tomatoes cat cat tomatoes }->{$1}
The Perl parser is getting mixed up about what you mean by the {} around qw. Instead of using the curly braces to create a hash ref it sees the curly braces as creating a code block. You can force {} to mean "create a hash" by putting a plus sign in front of it:
$text='The cat ate the bacon'; $text =~ s/(cat|tomatoes)/ +{qw(tomatoes cat cat tomatoes)}->{$1} /ge; print "The text is now $text\n";
This prints "The text is now The tomatoes ate the bacon"
See the section on creating hash references here: http://perldoc.perl.org/perlref.html
精彩评论