Единственное, что отсутствует в этом красивом макете, - это использование имен для подпрограммы и для переменной при формировании ha sh - вы не можете использовать эти вещи. затем, чтобы запустить подпрограмму или оценить переменную, используя только их простые имена.
Вместо этого вы можете взять ссылку на подпрограмму , которая является скаляром и, таким образом, может быть ha sh значение, после чего подпрограмма может быть выполнена путем разыменования его; и используйте переменную в качестве значения.
The ha sh
my %flv_hash = (
flavor_1 => {
data => { ... },
var => $f1_path,
code => \&subroutine_to_process_flavor_1_data,
},
flavor_2 => {
data => { ... },
var => $f2_path,
code => \&subroutine_to_process_flavor_2_data,
},
);
(это code
для ключа - всего лишь заполнитель для лучшего имени). Чтобы использовать это, как указано,
foreach my $flavor ( keys %flv_hash ) {
if (defined $flv_hash{$flavor}{var}) {
$flv_hash{$flavor}{code}->( $flv_hash{$flavor}{var} );
}
}
Синтаксис \&sub_name
принимает и возвращает ссылку на подпрограмму , а также скаляр, который может быть назначен и / или обработан как любой другой скаляр.
Другой способ создания такой ссылки на код - использовать анонимную подпрограмму , напрямую назначая код подпрограммы с использованием синтаксиса
my $code_reference = sub { subroutine-code };
что вы также могли бы сделать в своем ha sh (code => sub { ... }
), если бы подпрограммы были короткими и удобными.
Тогда обозначение $coderef->( LIST )
- это то, как мы выполняем подпрограмму со ссылкой на ее скаляр переменная $coderef
. Если аргументов нет, нам нужны пустые скобки.
Конечно, есть несколько способов организовать это, если вы примете ссылки на код; Я просто следую разумному намерению из вопроса. Еще один элемент, который может быть полезен в этом ключе, - это таблица отправки ; одна недавняя ссылка находится на этой странице и многих других.
См. также, например, этот пост и многое другое эту статью из Эффективный перлер ... и c.
Мне пришло в голову, что, возможно, могут понадобиться и сами под-имена.
Простой способ получить имя из ссылки на код - использовать Sub :: Util
use Sub::Util qw(subname);
say subname( $coderef );
Это в ядре, так как, я думаю, perl -5.22.0 (?). Также есть Sub :: Identify на CPAN.
Затем всемогущий B дает это и многое другое через svref_2oject($coderef)
, что для ссылки на код возвращает B :: CV объект, на котором также могут использоваться методы B :: GV
use B qw(svref_2object);
my $cv = svref_2oject($coderef);
say for $cv->FILE, $cv->GV->NAME; # etc