in reply to Re^3: Stupid question about strings...
in thread Stupid question about strings...

You appear to have (most of) the angels on your side.

So why did the code I showed return true (or "foo")?"


Quis custodiet ipsos custodes. Juvenal, Satires

Replies are listed 'Best First'.
Re^5: Stupid question about strings...
by AnomalousMonk (Archbishop) on Jul 14, 2014 at 23:48 UTC
    C:\>perl -E "my $str1 = qq(|L|D|); my $str2 = qr(\|L\|);if ($str2 =~ $ +str1) { say 'foo';}" foo
    So why did the code I showed return true (or "foo")?"

    Because the string defining the regex used in the  $str2 =~ $str1 expression (i.e., $str1) has the empty pattern as two (!) of its alternatives, and the empty pattern matches everything.

    my $str1 = qq(|L|D|); has the empty pattern twice. It doesn't really matter what else is present. The stringization of the output of the  qr(\|L\|) expression is a bit complex, but it could be anything.

    c:\@Work\Perl>perl -wMstrict -le "my $str1 = qq(|L|D|); my $str2 = qr(\|L\|); print qq{stringization of qr// output: '$str2'}; if ($str2 =~ $str1) { print 'foo'; } " stringization of qr// output: '(?^:\|L\|)' foo c:\@Work\Perl>perl -wMstrict -le "my $str1 = qq(|X|Y|); my $str2 = qr(\|L\|); if ($str2 =~ $str1) { print 'foo'; } " foo c:\@Work\Perl>perl -wMstrict -le "my $str1 = qq(|X|Y|); my $str2 = qq(aaaaa); if ($str2 =~ $str1) { print 'foo'; } " foo

    Update: Changed  my $str2 = qq(xyzzy); in third code example above to  qq(aaaaa) to eliminate any question of case-insensitive matching.

Re^5: Stupid question about strings...
by Laurent_R (Canon) on Jul 15, 2014 at 08:26 UTC
    Hi ww,

    So why did the code I showed return true (or "foo")?"

    The first part of my previous message with its two examples was intended to show with a simpler example on which sides of the binding operator each string should be.

    The second part of my message was intended to show with three additional examples where the error was in your example and how to correct it.

    Basically, since you put $str1 on the right side of the operator and did not quotemeta it and also did not escape the pipe characters, $str1 is interpreted as a regex and the pipe considered as an alternation within this regex. The "|L|D|" regex matches either an L, or a D, or any other character, so that in the end it matches pretty much anything.

    Escaping the pipe characters ("\|L\|D\|"), or using the quotemeta \Q operator, as I did in my examples corrects the issue.

Re^5: Stupid question about strings...
by ww (Archbishop) on Jul 15, 2014 at 12:18 UTC

    Thank you both, AnomalousMonk and Laurent_R.

    You've made clear something that previous (careless?) readings of the docs left me in a blindspot in which I conflated 'quotemeta' (as a generic descriptor) with q, qq, qr.... instead of understanding that quotemeta() IS an operator in its own right.

    So, FTR, both versions of this code produce identical output:

    C:\> perl -E "my $str = qq(|g|h|i); my $strQ = qq(\Q|g|h|i\E); say quo +temeta($str); say $strQ;" \|g\|h\|i \|g\|h\|i

    P.S. Technically, this reply is directed to /me, but is done deliberately to acknowledge both previous replies and their authors.


    Note to self: RTFM -- more carefully!

      I guess you mixed up the "quote and quote-like" operators (q, qq, qr, qw...) with the "quotemeta" operator. There has been a point of time in the past where the distinction wasn't that clear to me either.