3

我正在定义一个带有可选参数的方法。通常我会使用这样的东西:

sub foo {
    ($self, $optarg) = @_;
    $optarg ||= 1;
}

我希望将可选参数视为布尔值,默认值为true. 这显然不适用于上述情况,因为$optarg如果未传入参数,则会评估为 false。

有没有办法区分没有传递的参数和评估为假的值?

4

5 回答 5

10

如果您有 Perl 版本 5.10 或更高版本,则可以替换$optarg ||= 1为,仅当它是$optarg //= 1时才会修改。$optargundef

或者,如果您想允许undef作为显式 false 值传递,您可以说$optarg = 1 if @_ < 2.

于 2013-01-11T00:03:13.993 回答
4
my ( $self, $optarg ) = ( @_, 1 );

如果它是“未传入”,那么它将不在列表中,您将获得1. 否则,假设用户知道该方法是如何工作的,他们不应该传入任何可以被视为假的第二个参数,除非他们意味着将其视为假值。(当然,我并不是说知识渊博的用户永远不会为布尔值传递错误的值。)

于 2013-01-10T23:55:31.157 回答
4

这可以很好地扩展到多个可选参数:

my $self = shift;
my $optarg = @_ ? shift : 1;

这样做也是如此,但它可以更好地处理多个必需的参数。不幸的是,它违反了最小冗余原则。

my ($self, $optarg) = @_;
$optarg = 1 if @_ < 2;
于 2013-01-11T00:57:56.703 回答
2

你已经得到了一些很好的回应,所以我只想添加一个更多可能的选项。Method::Signatures为带有签名的方法提供了一个很好的语法,包括默认值,以您期望的方式处理。

#!/usr/bin/env perl

package MyClass;

use Moo;
use Method::Signatures;

method foo ( $optarg = 1 ) {
  print "$optarg\n";
}

package main;

my $obj = MyClass->new;
$obj->foo;
$obj->foo(0);

请注意,我使用Moo,但 M::S 不需要它。另请注意,Moo 启用strict并且此脚本是strict安全的,即使它可能看起来不安全。

于 2013-01-11T14:47:16.563 回答
1
my $optarg;
$optarg = 1 if not defined $optarg;

但请注意下面@jordanm 的评论

于 2013-01-10T23:54:12.087 回答