http://qs1969.pair.com?node_id=619623

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

I get the error
Can't use string ("") as a subroutine ref while "strict refs"
 the corresponding code is
my $var1; my $var2; my $regex=qr/^Device(\s)+Configuration/; tie %functions, 'Tie::RegexpHash'; %functions = ( ($regex => \&get_device); my $result = $functions{$var1}->($var2);
if I use a string as the key the code works, how can I expand the regex correctly for the function to use it?

Replies are listed 'Best First'.
Re: Using a regex as a hash key
by japhy (Canon) on Jun 06, 2007 at 16:17 UTC
    Your code a syntax error (an extra "(") on line 5. You also haven't provided any value for $var1.

    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: Using a regex as a hash key
by ikegami (Patriarch) on Jun 06, 2007 at 17:00 UTC

    $functions{$var1} returned undef because none of the regexp keys matched, so $functions{$var1}->($var2) gives that error. The fix is to check whether a key was found in the hash:

    my $handler = $functions{$var1}; if (not defined $handler) { ... } my $result = $handler->($var2);

    Perhaps it's because you never assigned a value to $var1?

Re: Using a regex as a hash key
by citromatik (Curate) on Jun 06, 2007 at 16:51 UTC

    "use strict" to catch errors in your code

    An example of how to use Tie::RegexpHash could be:

    use strict; use warnings; use Tie::RegexpHash; my $regex1=qr/^\d+$/; my $regex2=qr/^\D+$/; my $regex3=qr/^.+$/; my %functions; tie %functions, 'Tie::RegexpHash'; %functions = ( $regex1 => sub {print "Number\n"}, $regex2 => sub {print "Not number\n"}, $regex3 => sub {print "Mixed\n"} ); while (<>){ last if /^$/; $functions{$_}->(); }

    Hope this helps!

    citromatik

Re: Using a regex as a hash key
by halley (Prior) on Jun 06, 2007 at 16:47 UTC
    Either keep your original key $regex around,
    my $regex=qr/^Device(\s)+Configuration/; ... my $result = $functions{$regex}->($var2);
    or traverse the hash as usual:
    my $result = undef; for (keys %functions) { if (this_is_the_key_I_want($_)) { $result = $functions{$_}->($var2); last; } }
    The check for this_is_the_key_I_want() is optional of course, or you could scan the regex itself as if it were a string, such as /Config/.

    --
    [ e d @ h a l l e y . c c ]

        ikegami, I recognized that it's a TRH, but it still behaves like a hash including iteration, as well as the extra features and odd non-1:1 key behavior. If he doesn't have anything for a key (his missing $val1), he'll have to start somewhere.

        Perhaps I should have said he could just assign $val1 = 'Devices Configuration for Hard Drives' to pick out one particular key, or the hail-mary dispatch loop that citromatik offers where you just throw any old $_ in there and hope it sticks.

        --
        [ e d @ h a l l e y . c c ]