对于将某些参数传递给构造函数类型的不同方法,我有点模糊不清。我想只传递哈希引用\%hash
或列表foo => 1, bar => 1
但不能同时传递croak
,如果还有其他内容通过,( single elements, array reference )
。
例如,我传递了我的引用或列表.. (This works for the way I do this)
my $obj = foo->new;
my $data = $obj->dump( \%hash );
my $data = $obj->dump( foo => 1, bar => 1 );
或
my $obj = foo->dump( \%hash );
my $obj = foo->dump( foo => 1, bar => 1 );
包装模块:
package foo;
use strict;
use Carp;
use Scalar::Util qw/reftype/;
sub new { return bless {}, shift }
sub dump {
my $class = shift;
my $self = shift;
unless ( reftype( $self ) eq reftype {} ) {
croak("Constructor method not a hash type!");
}
}
1;
我也考虑过在这里使用条件运算符? :
,但我无法正确地将其误解。
my $self = reftype($_[0]) eq reftype {} ? shift : {@_};
有更好的首选方法吗?
答案 0 :(得分:2)
我们可以查看可以调用dump
方法的各种方法。
如果我们传递“哈希列表”,则元素数量是偶数(@_ % 2 == 0
)。此外,如果存在至少一个键值对,则第一个参数(键)是一个字符串,因此not defined reftype $_[0]
成立。
如果我们传递一个哈希引用,那么参数列表应该只保存这个引用,而不是其他值:@_ == 1
。第一个参数是哈希:reftype($_[0]) eq 'HASH'
。
因此,要将参数放在哈希引用中,可以执行以下操作:
sub dump {
my $invocant = shift;
my $hashref;
if (@_ == 1 and reftype $_[0] eq 'HASH') {
$hashref = $_[0];
} elsif (@_ % 2 == 0 and (@_ == 0 or not defined reftype $_[0])) {
$hashref = +{ @_ };
} else {
croak "Unknown argument format: either pass a hashref, or an even-valued list";
}
...; # do something with $hashref
}
要确定$invocant
是否是类名或对象,只需询问它是否有福:
if (defined Scalar::Util::blessed $invocant) {
say "Yep, it is an object";
} else {
say "Nope, it is a package name";
}
答案 1 :(得分:2)
没有“哈希列表”这样的东西。 foo => 1, bar => 1
,只是一个四元素列表。听起来你想接受散列引用甚至是args的数量。
sub dump {
my $self = shift;
my %args;
if (@_ == 1) {
croak("...") if (ref($_[0]) // '') ne 'HASH';
%args = %{ $_[0] };
} else {
croak("...") if @_ % 2 != 0;
%args = @_;
}
...
}