在Perl中是否有安全解除引用的便利?
所以perl5porters正在讨论添加一个安全的解引用操作符,以允许像这样的东西在Perl中是否有安全解除引用的便利?,perl,operators,dereference,Perl,Operators,Dereference,所以perl5porters正在讨论添加一个安全的解引用操作符,以允许像这样的东西 $ceo_car_color = $company->ceo->car->color if defined $company and defined $company->ceo and defined $company->ceo->car; 缩短为,例如 $ceo_car_color = $company->>ceo->>ca
$ceo_car_color = $company->ceo->car->color
if defined $company
and defined $company->ceo
and defined $company->ceo->car;
缩短为,例如
$ceo_car_color = $company->>ceo->>car->>color;
其中$foo->条表示定义的$foo$foo->bar:undef
问题是:是否有一些模块或非结构化的黑客让我得到了这个操作符,或者类似的行为,并且语法直观
为了让你们高兴,我将列出我能想到的想法
多重解除防护方法(看起来很难看)
将undef
转换为代理对象(看起来更丑陋)的包装器,该代理对象从所有函数调用返回undef
{ package Safe; sub AUTOLOAD { return undef } }
sub safe { (shift) // bless {}, 'Safe' }
$ceo_car_color = safe(safe(safe($company)->ceo)->car)->color;
由于我可以访问ceo()
、car()
和color()
的实现,因此我考虑直接从这些方法返回安全代理,但现有代码可能会中断:
my $ceo = $company->ceo;
my $car = $ceo->car if defined $ceo; # defined() breaks
不幸的是,我在perldoc重载
中没有看到任何关于重载我的安全代理中定义的和/
的含义的内容
您可以使用eval
:
$ceo_car_color = eval { $company->ceo->car->color };
但是它当然会捕获任何错误,而不仅仅是在undef
上调用一个方法。也许这不是最有用的解决方案,但它又是一个WTDI(nr.1的一个变体),它是非常罕见的'sreduce的一个非常重要的用例
代码
输出
注:
当然应该是
return unless defined $a;
$a = $a->$b;
与上面的较短的$a和$a=$a->$b
不同,它可以正确地处理已定义但为假的值,但我这里的重点是使用reduce数字2赢得最奇怪的一个。有趣的解决方案。感谢分享。实际上,让multicall成为$obj的成员会使语法非常可爱。对于在大型代码库中偶然发现该文档的人来说,该文档是可以发现的。我现在使用此解决方案,不过我可能会编写类似于$obj->multicall(foo=>bar=>baz=>)的调用。
。
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use List::Util 'reduce';
my $answer = 42;
sub new { bless \$answer }
sub foo { return shift } # just chaining
sub bar { return undef } # break the chain
sub baz { return ${shift()} } # return the answer
sub multicall { reduce { our ($a, $b); $a and $a = $a->$b } @_ }
my $obj = main->new();
say $obj->multicall(qw(foo foo baz)) // 'undef!';
say $obj->multicall(qw(foo bar baz)) // 'undef!';
42
undef!
return unless defined $a;
$a = $a->$b;