Why is `$ str1 = ~" foo "` recognized as `$ str1 = ~ m / foo /` (and not a syntax error)?

I recently saw code from someone who is not familiar with Perl. He wanted to compare two lines for equality, but did not know about the eq operator, so he used =~ as follows:

 my $str1 = 'foobar'; my $str2 = 'bar'; if ( $str1 =~ $str2 ) { print "strings are equal\n"; } 

Another fragment was

 if ( $str1 =~ "foo" ) { print "string equals 'foo'\n"; } 

Of course, he should just read $str1 eq $str2 and $str1 eq "foo" to avoid false positives.

I run the code through Deparse , and he said that everything is fine:

 $ perl -MO=Deparse -e 'use strict; use warnings; my $str1="foobar"; my $str2="bar"; $str1 =~ $str2; $str1 =~ "bar";' use warnings; use strict; my $str1 = 'foobar'; my $str2 = 'bar'; $str1 =~ /$str2/; $str1 =~ /bar/; -e syntax OK 

I looked through the docs , but from my understanding the situation is this:

  • The general syntax is m/pattern/ .
  • Use m and the separator of your choice instead of / (but keep in mind that ' and ? Have special meaning)
  • Or leave m , but the separator should be / .

But, apparently, Perl understands $str1 =~ "foo" as $str1 =~ m/foo/ , although there is no m . Why is this? I expected this to be a syntax error.

+7
regex perl
source share
2 answers

I expected this to be a syntax error.

Labeling the documentation for =~ in perlop ,

If the correct argument is an expression, not a search pattern, wildcard, or transliteration, it is interpreted as a run-time search pattern.


But, apparently, Perl understands $str1 =~ "foo" as $str1 =~ m/foo/ , although there is no m . Why is this?

Why not? I cannot think of a reason when =~ implies a match operator if there is no match, replace, or transliteration operator on its RHS. I would use

 $s =~ /foo/ 

above

 $s =~ "foo" 

but i used

 $s =~ $re 

Especially when the value of $re is a template compiled by qr// .

+4
source share

The operator =~ expects the scalar expression to not match on the left and the pattern on the right. From the documentation :

Binary "= ~" associates a scalar expression with pattern matching. Some operations search or change the default $ _ string. This statement does such work on some other line. The correct argument is a search pattern, wildcard, or transliteration. The left argument is what you are looking for, replacing, or transliterating instead of the standard $ _.
...
If the correct argument is an expression, not a search pattern, substitution, or transliteration, it is interpreted as a search pattern at runtime.

The actual interpretation of the right side can be ... complicated. Details can be found in the Perl documentation, "Information on the Representation of Quoted Structures," by Gory , a summary of which:

When presenting something that may have several different interpretations, Perl uses the DWIM principle (which "does what I mean") to select the most likely interpretation. This strategy is so successful that Perl programmers often are unaware of the ambivalence of what they write. But from time to time, the concepts of Perl differ significantly from what the author had in mind ....
The most important rule of Perl parsing is the first, which is discussed below: when processing a quoted construct, Perl first finds the end of this construct and then interprets its contents. If you understand this rule, you can skip the rest of this section on first reading. Other rules, most likely, will contradict the user's expectations much less often than this first one.

+3
source share

All Articles