我宁愿这样做:
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方式.
您可以使用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经常使用,很容易忘记这些.
保罗
我假设你的第二个例子最好是:
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()全局函数,因此它可能比我的方法慢很多.