У вас уже есть несколько хороших ответов о том, как построить таблицу диспетчеризации и вызывать функции через нее в одном файле, но вы также продолжаете говорить о желании определить функции в других модулях. Если это так, то не лучше ли динамически создавать таблицу диспетчеризации, основываясь на том, какие диспетчерские функции, как говорит каждый модуль, у него есть, вместо того, чтобы беспокоиться о том, чтобы обновлять ее вручную? Конечно, это будет!
Для демонстрации этого требуется несколько файлов, и я использую Module :: Pluggable из CPAN, чтобы найти модули, предоставляющие определения функций.
dispatch_core.pl:
#!/usr/bin/env perl
use strict;
use warnings;
my %dispatch;
use lib '.'; # a demo is easier if I can put modules in the same directory
use Module::Pluggable require => 1, search_path => 'DTable';
for my $plugin (plugins) {
%dispatch = (%dispatch, $plugin->dispatchable);
}
for my $func (sort keys %dispatch) {
print "$func:\n";
$dispatch{$func}->(2, 5);
}
DTable / Add.pm:
package DTable::Add;
use strict;
use warnings;
sub dispatchable {
return (add => \&add);
}
sub add {
my ($num1, $num2) = @_;
print "$num1 + $num2 = ", $num1 + $num2, "\n";
}
1;
DTable / MultDiv.pm:
package DTable::MultDiv;
use strict;
use warnings;
sub dispatchable {
return (multiply => \&multiply, divide => \÷);
}
sub multiply {
my ($num1, $num2) = @_;
print "$num1 * $num2 = ", $num1 * $num2, "\n";
}
sub divide {
my ($num1, $num2) = @_;
print "$num1 / $num2 = ", $num1 / $num2, "\n";
}
1;
Затем в командной строке:
$ ./dispatch_core.pl
add:
2 + 5 = 7
divide:
2 / 5 = 0.4
multiply:
2 * 5 = 10
Добавление новых функций теперь так же просто, как перенос нового файла в каталог DTable с соответствующим подпрограммой dispatchable
. Не нужно когда-либо касаться dispatch_core.pl
, просто чтобы снова добавить новую функцию.
Редактировать: В ответ на вопрос о том, можно ли это сделать без Module :: Pluggable, вот модифицированный dispatch_core.pl, в котором не используются никакие внешние модули, кроме тех, которые определяют диспетчеризуемый функции:
#!/usr/bin/env perl
use strict;
use warnings;
my %dispatch;
my @dtable = qw(
DTable::Add
DTable::MultDiv
);
use lib '.';
for my $plugin (@dtable) {
eval "use $plugin";
%dispatch = (%dispatch, $plugin->dispatchable);
}
for my $func (sort keys %dispatch) {
print "$func:\n";
$dispatch{$func}->(2, 5);
}