开发者

Why two `{` is required here?

开发者 https://www.devze.com 2023-03-16 06:30 出处:网络
$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> }->{$
$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

0

精彩评论

暂无评论...
验证码 换一张
取 消