+5  A: 

\&func1 is a subroutine reference, but \&func1(\@arraydata) is a reference to the value returned by a call to &func1. Try instead just: "ab 1" => \&func1, .... The passing of @arraydata is correct in your dispatch code.

Note that /$k/ will make metacharacters like . or * have their special effect in the regex; if you don't want that, do /\Q$k/ instead. Or possibly you want just eq $k?

ysth
+6  A: 

Hashes are initialized with regular parens ( ( ) ), not curly brackets (those are for hash references.) And you initialize a hash with a list assignment. So the first part should be:

my %commandfunc = ( 
    "ab 1" => \&func1,
    "ab 2" => \&func2,
    "ab 3" => \&func3
);

The => operator is a little prettier than using a comma and has the added benefit of quoting barewords on the left side, if necessary.

I'm not sure what you're trying to match in your loop (where does $_ come from?) But you can do something like this:

foreach my $k (keys %commandfunc) {
    if( $something =~ /$k/) {
        my $result = $commandfunc{$k}->( \@arraydata );
    }
}
friedo
well,to make it clear,yes I want to match a key string ($k) with $something...
mhd
apparently I dont need passing array by reference, by value is ok.Thanks..
mhd
+3  A: 

You weren't really clear whether @arraydata was defined up front or not, and how often this code would be executed. A direct translation of your attempt would yield:

my %commandfunc = (
    "ab 1" => sub { func1(@arraydata) },
    "ab 2" => sub { func2(@arraydata) },
    "ab 3" => sub { func3(@arraydata) },
};

if (my ($match) = grep { $_ eq $key } keys %commandfunc)
{
    my $result = &{$commandfunc{$match}};
}

However this is not very efficient - the %commandfunc hash is being defined with anonymous subroutine closures, when we could instead just store coderefs to the original subs with no arguments bound, and pass in an array later:

my %commandfunc = (
    "ab 1" => \&func1,
    "ab 2" => \&func2,
    "ab 3" => \&func3,
};

and call it like this:

my $result = $commandfunc{$match}->(@array);
Ether
looking at mhd's code, I decided that since @arraydata was being passed at the time of dispatch, this couldn't be what he meant.
ysth
@ysth: aye, so making a table of simple coderefs would be more appropriate then.
Ether