[ stealth cc's considered harmful ]

Dossy graced us by uttering:
> On 2002.05.18, Tim Hammerquist <tim / vegeta.ath.cx> wrote:
>> The main problem I see with this (even as a perl idiom) is that you're
>> attempting to assign variables without checking the success of the
>> match.  Without knowing the actual code you'll be using this example
>> with, it's a valid warning that, if the regex doesn't match the string,
>> then x would be assigned the result of the match (nil) and y would
>> retain the value it held before the statement (possibly nil as well).
>> 
>> A more perlish idiom would be:
>> 
>>   if ("foo bar" =~ /(foo) (bar)/) {
>>     ($x, $y) = ($1, $2);
>>   }
> 
> No, the Perlish idiom is:
> 
>   ($x, $y) = ("foo bar" =~ /(foo) (bar)/);
> 
> As I said, this is more Perl wantarray() envy.  In perl, the =~
> operator knows if it's being used in the context of expecting a
> scalar vs. an array.  If it's a scalar context, it returns 1 if
> there was a match or 0 if there wasn't.  In an array context,
> it returns $1..$n match expressions as an array.

As I said, I don't know what codebase you'll be using this in, but you
seem very certain that the string will _always_ match the regex.  This
is just not an assumption real experiences have let me make safely.
Just a small difference in either part of the match and you'd continue
using the $x and $y vars even though they're undefined (Perl) or nil
(Ruby).

Consider each of the following

    ($x, $y) = ( "foo  bar" =~ /(foo) (bar)/ );
    ($x, $y) = ( "foo baar" =~ /(foo) (bar)/ );
    ($x, $y) = ( "foobar"   =~ /(foo) (bar)/ );
    ($x, $y) = ( "foo_bar"  =~ /(foo) (bar)/ );
    ($x, $y) = ( "foo\tbar" =~ /(foo) (bar)/ );
or:
    ($x, $y) = ( "foo bar" =~ /(foo)  (bar)/ );
    ($x, $y) = ( "foo bar" =~ /(foo)(bar)/   );
    ($x, $y) = ( "foo bar" =~ /(foo)_(bar)/  );

....ad infinitum.  In each case, $x and $y are left empty and (as far as
your code tells us) your program continues on oblivious.

You must not have ever heard Randal Schwartz
speak on checking the success of regexen.
<http://groups.google.com/groups?q=randal+schwartz+regex+success>

Following is one of the dozens of times Randal has spoken about this:
> From: Randal L. Schwartz (merlyn / stonehenge.com)
> Subject: Re: Pattern Match Arguments in Variable
> Newsgroups: comp.lang.perl.misc
> Date: 2001-09-16 11:20:52 PST 
> 
[ snip ]
> While this is a great piece of code to demonstrate how the $flag works
> here, it also triggers one of my pet peeves leading to faulty code:
> the examination of the memory variables (like $1) without testing
> the success of the regex match, which can lead to faulty or (worse)
> insecure behavior.  I'd write that as:
> 
>     $flag = "(?i)";   #  or $flag = "";
>     if ("test string" =~ /$flag(S)/) {
>         print "$1\n";
>     } else {   print "no match\n";
>     }
> 
> Otherwise, on a failed match, the $1 you're printing is the *previous*
> match's $1.  Probably unexpected by some who don't understand the
> rule, that the memories are left unchanged on any *unsuccessful*
> match.
[ snip ]

Yes, he's talking about Perl. However, Ruby's behavior mimics Perl's,
at least insofar as "nothing changes if nothing matches".  And Randal
know's what he's talking about.  He's one of the few old-school Perl
gurus who still frequent comp.lang.perl.misc, the rest having been
chased off by newbies and halfbies not listening.

Linux Magazine features a monthly column by Mr. Schwartz, as well.  In
fact, it was the April 2002 issue of Linux Magazine that featured Ruby
on the cover...

But oh well. Someone who's been programming and hacking for over 30
years and probably fixed more bugs than I've had the chance to _make_
probably doesn't even know what he's talking about... Ne?

Tim Hammerquist
-- 
Error: No keyboard detected. Press F1 to continue.
    -- actual MS Windows error message