Perl有和吗?

Fre*_*idt 4 perl andand

我宁愿这样做:

say $shop->ShopperDueDate->andand->day_name();
Run Code Online (Sandbox Code Playgroud)

与此:

say $shop->ShopperDueDate->day_name() if $shop->ShopperDueDate;
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

(这个想法是由红宝石启发andand扩展.)

(实际上它的灵感来自Groovy语言,但大多数人都不知道;-)

更新:我认为may()和eval {}都是很好的解决方案.这不是ruby,所以我不能期望从左到右阅读所有的方法/功能,所以也许肯定会有所帮助.当然,eval确实是实现它的perl方式.

pjf*_*pjf 9

您可以使用Perl的eval语句来捕获异常,包括尝试在未定义的参数上调用方法的异常:

eval {
    say $shop->ShopperDueDate->day_name();
};
Run Code Online (Sandbox Code Playgroud)

由于eval返回评估的最后一个语句,或者undef失败,您可以在变量中记录日期名称,如下所示:

my $day_name = eval { $shop->ShopperDueDate->day_name(); };
Run Code Online (Sandbox Code Playgroud)

如果您确实希望检查异常,可以查看特殊变量$@.这通常是Perl的内置异常的简单字符串,但如果异常源自autodie或使用对象异常的其他代码,则可能是完整的异常对象.

eval {
    say $shop->ShopperDueDate->day_name();
};

if ($@) {
    say "The error was: $@";
}
Run Code Online (Sandbox Code Playgroud)

也可以使用eval块将一系列命令串在一起.以下仅检查是否是周末,前提是我们在查找时没有任何异常$day_name.

eval {
    my $day_name = $shop->ShopperDueDate->day_name();

    if ($day_name ~~ [ 'Saturday', 'Sunday' ] ) {
        say "I like weekends";
    }
};
Run Code Online (Sandbox Code Playgroud)

您可以认为与其他语言eval相同try; 实际上,如果您使用CPAN中的错误模块,那么您甚至可以拼写它try.值得注意的是,eval的块形式(我上面已经演示过)并没有性能损失,并且与其他代码一起编译.字符串形式eval(我没有显示)完全是一个不同的野兽,应该谨慎使用,如果有的话.

eval在技​​术上被认为是Perl中的一个声明,因此是在块的末尾你会看到一个分号的少数几个地方之一.如果你不eval经常使用,很容易忘记这些.

保罗


geo*_*car 9

我假设你的第二个例子最好是:

say $shop->ShopperDueDate ? $shop->ShopperDueDate->day_name() : undef;
Run Code Online (Sandbox Code Playgroud)

而不是它实际上说的.

无论如何,如果没有源过滤器,你就无法使用完全没有源过滤器的语法,因为undef它不是一个对象,而是一元运算符,所以它不能有任何方法.

相反,考虑一下:

package noop; 
our $maybe = bless [], 'noop';
sub AUTOLOAD { undef };
Run Code Online (Sandbox Code Playgroud)

$noop::maybe是一个对象; 它的所有方法都返回undef了.在其他地方,你将有一个像这样的常规函数​​:

sub maybe { $_[0] || $noop::maybe; }
Run Code Online (Sandbox Code Playgroud)

然后你可以这样写:

say maybe($shop->ShopperDueDate)->day_name()
Run Code Online (Sandbox Code Playgroud)

这是因为"maybe"返回如果为true则返回其参数,否则返回我们的$noop::maybe对象,该对象具有始终返回undef的方法.

编辑:更正!该->andand->语法可以可以了,而不源过滤器,通过使用XS与Perl的内部渣土约.Leon Timmermans做了一个实现这条路线.它取代了undef()全局函数,因此它可能比我的方法慢很多.