pianogirl95 has asked for the wisdom of the Perl Monks concerning the following question:

I'm using Switch with a series of pattern matches. Inside the case statement, I need to use $1($2, etc) from my pattern match. However, $1 isn't changing after the match. Is there something else I can use to access $1 or do I need to re-match inside the case statement? example:
switch ($val) { case /^\s*(\S+)$/{ print "$1\n"; }
I ended up just preserving $1 inside are var before the switch. I've never had a problem using Switch, and for this code (sorry, can't post it) I have a several nested if's inside of each case. I'll test it again and see if removing the switch improves performance.

Replies are listed 'Best First'.
Re: Switch and $1?
by Corion (Patriarch) on Jun 14, 2005 at 21:11 UTC

    Do not use Switch.pm - it is a bad idea gone horribly wrong and will cause you hard to find bugs merely by its presence in your code.

    As you didn't show the full code, I can't really make any better recommendation, but a set of if ... elsif ... isn't much worse to type than switch.

    Update: Here are some local discussions of things to do instead of using switch: Switch.pm or possible alternatives, and here is discussion of some error as introduced by switch - I don't know if the code on quantums scratchpad is still there though.

Re: Switch and $1?
by jeffa (Bishop) on Jun 14, 2005 at 21:19 UTC

    To further Corion's excellent advice, you most likely don't need to directly use $1, $2, etc. either. This code:

    my $str = 'hello world'; $str =~ /^(\S+)\s/; print $1;
    Is most often better written like so:
    my $str = 'hello world'; my ($match) = $str =~ /^(\S+)\s/; print $match;
    In other worsds, capture your match in your own variable. :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: Switch and $1?
by ikegami (Patriarch) on Jun 14, 2005 at 21:32 UTC

    $1 appears to be localised into the function that calls the regexp. In this case, that's some anonymous function created somewhere inside of Switch.pm.

    If you still want to use Switch, and you can't stand the repetition, try the following:

    my $dollar1; case /^\s*(\S+)$ (?{ $dollar1 = $1 })/ { ...

    I don't have Switch, so I didn't test the above. Here's a proof of concept, though:

    use strict; use warnings; sub do_re { my ($re, $var) = @_; $var =~ /$re/; print("inside: $1\n"); } { my $re = qr/(b)/; print("$re\n"); do_re($re, 'abc'); if (defined($1)) { print("outside: $1\n"); } else { print("outside: [undef]\n"); } } print("\n"); { my $dollar1; my $re = qr/(e)(?{ $dollar1 = $1 })/; print("$re\n"); do_re($re, 'def'); if (defined($dollar1)) { print("outside: $dollar1\n"); } else { print("outside: [undef]\n"); } } __END__ (?-xism:(b)) inside: b outside: [undef] (?-xism:(e)(?{ $dollar1 = $1 })) inside: e outside: e

    I wasn't sure if it would use the lexical $dollar1 instead of the package variable by the same name, but it does.