Perl Dog Perl Dog - 2 months ago 10
Perl Question

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

I recently saw code from someone who's not familiar with Perl.
He wanted to compare two strings for equality but didn't know about
the

eq
operator, so he used
=~
like this:

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


Another snippet was

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


Of course it should simply read
$str1 eq $str2
and
$str1 eq "foo"
to avoid false-positives.

I run the code through
Deparse
and it said everything is ok:

$ 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 as follows:


  • The general syntax is
    m/pattern/
    .

  • Either use
    m
    and a delimiter of your choice instead of
    /
    (but be aware that
    '
    and
    ?
    have special meaning)

  • Or leave off the
    m
    but then the delimiter must be
    /
    .



But apparently Perl understands
$str1 =~ "foo"
as
$str1 =~ m/foo/
although no
m
is present. Why is that? I'd expected that to be a syntax error.

Answer

I'd expected that to be a syntax error.

Quoting the documentation for =~ in perlop

If the right argument is an expression rather than a search pattern, substitution, or transliteration, it is interpreted as a search pattern at run time.


But apparently Perl understands $str1 =~ "foo" as $str1 =~ m/foo/ although no m is present. Why is that?

Why not? I can't think of a reason not to have =~ imply a match operator if there's no match, substitution or transliteration operator on its RHS. I'd use

$s =~ /foo/

over

$s =~ "foo"

but I have used

$s =~ $re

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