【发布时间】:2014-02-23 16:14:46
【问题描述】:
在 perl 中进行防御性编程的最佳(或推荐)方法是什么? 例如,如果我有一个必须使用(定义的)SCALAR、ARRAYREF 和可选 HASHREF 调用的 sub。
我见过的三种方法:
sub test1 {
die if !(@_ == 2 || @_ == 3);
my ($scalar, $arrayref, $hashref) = @_;
die if !defined($scalar) || ref($scalar);
die if ref($arrayref) ne 'ARRAY';
die if defined($hashref) && ref($hashref) ne 'HASH';
#do s.th with scalar, arrayref and hashref
}
sub test2 {
Carp::assert(@_ == 2 || @_ == 3) if DEBUG;
my ($scalar, $arrayref, $hashref) = @_;
if(DEBUG) {
Carp::assert defined($scalar) && !ref($scalar);
Carp::assert ref($arrayref) eq 'ARRAY';
Carp::assert !defined($hashref) || ref($hashref) eq 'HASH';
}
#do s.th with scalar, arrayref and hashref
}
sub test3 {
my ($scalar, $arrayref, $hashref) = @_;
(@_ == 2 || @_ == 3 && defined($scalar) && !ref($scalar) && ref($arrayref) eq 'ARRAY' && (!defined($hashref) || ref($hashref) eq 'HASH'))
or Carp::croak 'usage: test3(SCALAR, ARRAYREF, [HASHREF])';
#do s.th with scalar, arrayref and hashref
}
【问题讨论】:
-
有不止一种方法可以做到这一点。所有方法都有其优点和缺点。有些方法比其他方法更惯用/可读/简洁/可维护。我认为下面的标题更适合这个问题:检查子例程参数的最惯用的方法是什么?
-
您考虑过 CPAN 产品吗?
Params::Validate和Type::Params看起来不错。
标签: perl assert die defensive-programming