Perl: .=~ 是什么意思
Perl: what's the meaning of .=~
在perl脚本中,我偶尔会写
my $s = "text";
$s .=~ " another text";
print "$s\n";
没有打印出预期的结果 text another text
,而是在我的终端中显示了奇怪的文本 textߞ������ߋ���
。
毫无疑问:错误是运算符 .=~
而实际上,我想写 .=
但我很好奇:为什么 .=~
不是语法错误?这个操作是什么意思?
.=~
是两个运算符,.=
和 ~
。波浪号是二元否定运算符,请参阅 perlop.
验证:
$ perl -MO=Deparse,-p -e '$x .=~ $y'
($x .= (~$y));
-e syntax OK
当 choroba 不在时 ;) 你可以使用 B::Deparse and ppi_dumper 告诉你你正在处理什么(.=
和 ~
)
$ perl -MO=Deparse,-p -e " $foo .=~ /bar/; "
($foo .= (~/bar/));
-e syntax OK
$ ppi_dumper foo.pl
PPI::Document
PPI::Statement
PPI::Token::Symbol '$foo'
PPI::Token::Whitespace ' '
PPI::Token::Operator '.='
PPI::Token::Operator '~'
PPI::Token::Whitespace ' '
PPI::Token::Regexp::Match '/bar/'
PPI::Token::Structure ';'
当 Perl 做一些你在语法上不理解的事情时,你要么 B::Deparse 要么 B::Concise 弄明白。
B::Deparse
运行
$ perl -MO=Deparse
该代码产生:
my $s = 'text';
$s .= "7610372573273";
print "$s\n";
B::Concise
运行
$ perl -MO=Concise,-exec
该代码产生:
1 <0> enter
2 <;> nextstate(main 1 -:1) v:{
3 <$> const[PV "text"] s
4 <0> padsv[$s:1,2] sRM*/LVINTRO
5 <2> sassign vKS/2
6 <;> nextstate(main 2 -:2) v:{
7 <0> padsv[$s:1,2] sRM
8 <$> const[PV "7610372573273"] s
9 <2> concat[t3] vKS/2
a <;> nextstate(main 2 -:3) v:{
b <0> pushmark s
c <0> padsv[$s:1,2] s
d <$> const[PV "\n"] s
e <2> concat[t4] sK/2
f <@> print vK
g <@> leave[1 ref] vKP/REFC
在这两种情况下,答案是一样的。你有一个充满了一堆怪人字符的字面意思。这是编译器在编译时对文字应用一元按位取反 ~
,并将结果存储在解析树中的结果。
在perl脚本中,我偶尔会写
my $s = "text";
$s .=~ " another text";
print "$s\n";
没有打印出预期的结果 text another text
,而是在我的终端中显示了奇怪的文本 textߞ������ߋ���
。
毫无疑问:错误是运算符 .=~
而实际上,我想写 .=
但我很好奇:为什么 .=~
不是语法错误?这个操作是什么意思?
.=~
是两个运算符,.=
和 ~
。波浪号是二元否定运算符,请参阅 perlop.
验证:
$ perl -MO=Deparse,-p -e '$x .=~ $y'
($x .= (~$y));
-e syntax OK
当 choroba 不在时 ;) 你可以使用 B::Deparse and ppi_dumper 告诉你你正在处理什么(.=
和 ~
)
$ perl -MO=Deparse,-p -e " $foo .=~ /bar/; "
($foo .= (~/bar/));
-e syntax OK
$ ppi_dumper foo.pl
PPI::Document
PPI::Statement
PPI::Token::Symbol '$foo'
PPI::Token::Whitespace ' '
PPI::Token::Operator '.='
PPI::Token::Operator '~'
PPI::Token::Whitespace ' '
PPI::Token::Regexp::Match '/bar/'
PPI::Token::Structure ';'
当 Perl 做一些你在语法上不理解的事情时,你要么 B::Deparse 要么 B::Concise 弄明白。
B::Deparse
运行
$ perl -MO=Deparse
该代码产生:
my $s = 'text';
$s .= "7610372573273";
print "$s\n";
B::Concise
运行
$ perl -MO=Concise,-exec
该代码产生:
1 <0> enter
2 <;> nextstate(main 1 -:1) v:{
3 <$> const[PV "text"] s
4 <0> padsv[$s:1,2] sRM*/LVINTRO
5 <2> sassign vKS/2
6 <;> nextstate(main 2 -:2) v:{
7 <0> padsv[$s:1,2] sRM
8 <$> const[PV "7610372573273"] s
9 <2> concat[t3] vKS/2
a <;> nextstate(main 2 -:3) v:{
b <0> pushmark s
c <0> padsv[$s:1,2] s
d <$> const[PV "\n"] s
e <2> concat[t4] sK/2
f <@> print vK
g <@> leave[1 ref] vKP/REFC
在这两种情况下,答案是一样的。你有一个充满了一堆怪人字符的字面意思。这是编译器在编译时对文字应用一元按位取反 ~
,并将结果存储在解析树中的结果。