Как создать диспетчерскую таблицу в Perl с ключом, содержащим пробел и подпрограммой, принимающей параметр массива?

Вот мое текущее мышление, но я не знаю, как его отправить / выполнить

мой ключ $;
мой @arraydata;

мой% commandfunc {
"ab 1", \ & func1 (\ @ arraydata),
"ab 2", \ & func2 (\ @ arraydata,
"ab 3", \ & func3 (\ @ arraydata)
};

foreach $ k (keys% commandfunc) {
  if ($thing =~ /$k/){ #if $ что-то совпадает со строкой ключа
        $key= $k;
        # некоторая обработка массивов здесь;
    }

}
#dispatching??
my $ command = $ commandfunc {$ key} -> (\ @ arraydata);

Пожалуйста, исправьте мой код.. Большое спасибо

3 ответа

Решение

Хэши инициализируются обычными паренами (( )), а не фигурные скобки (это для ссылок на хеш.) И вы инициализируете хеш с помощью назначения списка. Итак, первая часть должна быть:

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

=> Оператор немного красивее, чем использование запятой и имеет дополнительное преимущество, заключающееся в цитировании голых слов на левой стороне, если это необходимо.

Я не уверен, что вы пытаетесь сопоставить в вашем цикле (где $_ откуда?) Но вы можете сделать что-то вроде этого:

foreach my $k (keys %commandfunc) {
    if( $something =~ /$k/) {
        my $result = $commandfunc{$k}->( \@arraydata );
    }
}

\&func1 ссылка на подпрограмму, но \&func1(\@arraydata) является ссылкой на значение, возвращаемое вызовом & func1. Попробуйте вместо этого просто: "ab 1" => \&func1, ..., Передача @arraydata правильна в вашем коде отправки.

Обратите внимание, что /$k/ сделает метасимволы как. или * имеют свой особый эффект в регулярном выражении; если ты этого не хочешь, делай /\Q$k/ вместо. Или, возможно, вы хотите просто eq $k?

Вам не очень понятно, @arraydata был определен заранее или нет, и как часто этот код будет выполняться. Прямой перевод вашей попытки даст:

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}};
}

Однако это не очень эффективно - %commandfunc Хэш определяется с помощью анонимных закрытий подпрограмм, когда вместо этого мы можем просто сохранить кодовые ссылки в исходных подпрограммах без привязки аргументов и передать массив позже:

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

и назовите это так:

my $result = $commandfunc{$match}->(@array);
Другие вопросы по тегам