5

そのため、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->>car->>color;

ここで$foo->>barを意味しdefined $foo ? $foo->bar : undefます。

質問:この演算子を取得するモジュールまたは目立たないハック、または視覚的に快適な構文を持つ同様の動作はありますか?

参考までに、私が思いついたアイデアを挙げておきます。

  1. 複数のデリファレンス方法 (見た目が悪い)。

    sub multicall {
        my $instance = shift // return undef;
        for my $method (@_) {
            $instance = $instance->$method() // return undef;
        }
        return $instance;
    }
    
    $ceo_car_color = multicall($company, qw(ceo car color));
    
  2. すべての関数呼び出しからundef返されるプロキシ オブジェクト (さらに醜く見える) に変わるラッパー。undef

    { package Safe; sub AUTOLOAD { return undef } }
    sub safe { (shift) // bless {}, 'Safe' }
    
    $ceo_car_color = safe(safe(safe($company)->ceo)->car)->color;
    
  3. ceo()car()およびの実装にアクセスできるのでcolor()、これらのメソッドから安全なプロキシを直接返すことを考えましたが、既存のコードが壊れる可能性があります。

    my $ceo = $company->ceo;
    my $car = $ceo->car if defined $ceo; # defined() breaks
    

    残念ながら、安全なプロキシperldoc overloadの意味をオーバーロードすることdefinedについては何もわかりません。//

4

2 に答える 2

3

これは最も有用なソリューションではないかもしれませんが、もう1つのWTDI(nr。1のバリアント)であり、List::Utilreduceの重要なユースケースです。これは非常にまれです。;)

コード

#!/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;

上から短くする代わりに、$a and $a = $a->$b定義されているが誤った値で正しく機能しますが、ここでの私のポイントは、reduceを使用することです。

于 2012-09-27T10:01:12.010 に答える
1

使用できますeval

$ceo_car_color = eval { $company->ceo->car->color };

しかし、もちろん、 でメソッドを呼び出すだけでなく、エラーをキャッチしますundef

于 2012-09-27T09:42:51.977 に答える