Reputation: 2071
In a perl script, I occasionally wrote
my $s = "text";
$s .=~ " another text";
print "$s\n";
The expected result text another text
was not printed, instead weird text as textߞ������ߋ���
was shown in my terminal.
No doubt: the error was the operator .=~
while indeed, I wanted to write .=
But I'm curious: Why isn't .=~
a syntax error? What's the meaning of this operation?
Upvotes: 3
Views: 450
Reputation: 80384
When Perl is doing something you don’t understand syntactically, you either B::Deparse or B::Concise to figure it out.
Running
$ perl -MO=Deparse
on that code yields:
my $s = 'text';
$s .= "\337\236\221\220\213\227\232\215\337\213\232\207\213";
print "$s\n";
Running
$ perl -MO=Concise,-exec
on that code yields:
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 "\337\236\221\220\213\227\232\215\337\213\232\207\213"] 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
In both cases, the answer is the same. You have a literal full of a bunch of weirdo characters. This is the result of compiler applying the unary bitwise negation ~
to the literal at compile time, and storing the result in the parse tree.
Upvotes: 8
Reputation: 2071
When choroba isn't around ;) you can use B::Deparse and ppi_dumper to tell you what you're dealing with ( .=
and ~
)
$ 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 ';'
Upvotes: 3