在一些perl函数中,我希望能够处理各种类型的参数,当然还要区别对待它们。现在我正在使用此ref
函数,并根据ref
结果执行相应的代码部分,例如
sub method_that_accept_various_data_types(){
if (ref $_[0] eq "ARRAY"){
# ...
}
elsif (ref $_[0] eq "SCALAR"){
# ...
}
elsif (ref $_[0] eq "HASH"){
# ...
}
}
是否有一些优雅的方式可以说我的所有功能都应遵循这种模式,或者我必须在所有子程序的开头使用提到的代码?我正在编写程序代码,类似的东西是OOP中的多态和继承,但我是这方面的新手。
修改 所有答案都需要将代码附加到所有新创建的函数。我问的是,对于现在定义的每个函数,是否有一些通用的方法,而不需要为新函数添加代码。
答案 0 :(得分:1)
你也可以使用函数/调度表的散列,但它基本上是相同的方法,
sub method_that_accept_various_data_types {
my $ref = ref($_[0]);
my $func = {
ARRAY => sub {
print "$ref\n";
},
SCALAR => sub {
print "$ref\n";
},
HASH => sub {
print "$ref\n";
},
}->{$ref} or return;
$func->(@_);
}
答案 1 :(得分:0)
您可以使用Switch
module
switch
声明
use Switch;
sub polymorph_function {
my ($arg1, $arg2, ...) = @_;
switch (ref $arg1) {
case 'ARRAY' { ... }
case 'HASH' { ... }
...
}
}
答案 2 :(得分:0)
我是基于Сухой27的例子添加这个作为额外的答案,因为我个人认为这是错误的代码。但如果你喜欢短代码,你可能会喜欢它:
sub polymorph_function {
({
ARRAY => sub { ... },
HASH => sub { ... },
...
}->{ref $_[0]} || return)->(@_);
}
它基本相同,只是没有临时变量。它创建一个匿名哈希,并直接取消引用其引用,并根据ref $_[0]
(第一个参数的类型)选择适当的密钥。然后立即使用原始子的所有参数调用对其中一个subs的结果coderef。
答案 3 :(得分:-1)
我只想过将大部分代码移到中心位置的方法。
sub polymorph_function {
poly \@_, (
ARRAY => sub { ... },
HASH => sub { ... },
...
);
}
sub poly {
my ($args, %subs) = @_;
my $sub = $subs{ref $args->[0]} or return;
$sub->( @$args );
}