Другие ответы верны, используя либо кодовую ссылку, либо псевдоним. Но примеры псевдонимов вводят синтаксис yicky typeglob и забывают иметь дело со строгим.
Псевдоним - это часто забываемый модуль, заключающий в себе всю магию, необходимую для присвоения имени ссылки, при этом сохраняя строгость.
use strict;
use Alias;
my $difference_method = $ARGV[0];
if( "square" eq $difference_method ) {
alias difference => sub { return ($_[0] - $_[1]) ** 2 };
}
elsif( "constant" eq $difference_method ) {
alias difference => sub { return 1 };
}
else {
die "Unknown difference method $difference_method";
}
А теперь difference($a, $b)
работает.
Если вам нужно только позвонить difference()
внутри вашего кода, т.е. вы не собираетесь экспортировать его как функцию, я бы просто использовал ссылку на код и забыл псевдоним.
my $difference_method = $ARGV[0];
my $Difference;
if( "square" eq $difference_method ) {
$Difference => sub { return ($_[0] - $_[1]) ** 2 };
}
elsif( "constant" eq $difference_method ) {
$Difference => sub { return 1 };
}
else {
die "Unknown difference method $difference_method";
}
$Difference->($a, $b);
Условное изменение того, что делает функция, усложняет выполнение кода и делает его менее гибким, подобно изменению поведения в любой глобальной среде. Это становится более очевидным, когда вы понимаете, что просто оптимизируете это:
my $Difference_Method = $ARGV[0];
sub difference {
if( $Difference_Method eq 'square' ) {
return ($_[0] - $_[1]) ** 2;
}
elsif( $Difference_Method eq 'constant' ) {
return 1;
}
else {
die "Unknown difference method $Difference_Method";
}
}
Каждый раз, когда у вас есть подпрограмма вида ...
sub foo {
if( $Global ) {
...do this...
}
else {
...do that...
}
}
У вас есть проблема.
Псевдоним наиболее полезен для генерации похожих функций во время выполнения с использованием замыканий, а не для вырезания и вставки их вручную. Но это для другого вопроса.