2

私たちのコードベースでは、この構造体を頻繁に使用して、プログラムのオプションを処理します。

Readonly my $ARGS => Getopt::Declare->new(
   join( "\n",
      '[strict]',
      "--option1 <some-option-description> [required]",
   )
) or exit(1);

問題は、厳密性に違反するGetopt::Declare->new(...)と が返されることです。これは、ブール値コンテキストで評価されるとtrueであるReadonly変数に格納されるundefことを除いて、通常は問題ありません。undef

  1. 明白な解決策は、 を削除することReadonlyであり、コードは期待どおりに機能します。ただし、これを変更すると変更できるため、このソリューションはあまり好きではありません$ARGS

    my $ARGS => Getopt::Declare->new(
       join( "\n",
          '[strict]',
          "--option1 <some-option-description> [required]",
       )
    ) or exit(1);
    
  2. 別の解決策は、括弧で囲み、 Readonly変数Getopt::Declare->new(...) or exit(1)に代入する前に評価されるようにすることです。

    Readonly my $ARGS => (
       Getopt::Declare->new(
          join( "\n",
             '[strict]',
             "--option1 <some-option-description> [required]",
          )
       ) or exit(1);
    )
    
  3. 代わりに or の優先順位の高いバージョンを使用することもあると思いますが||、これはより強力にバインド=>されますが、それが読みやすいかどうかはわかりません。

    Readonly my $ARGS => Getopt::Declare->new(
       join( "\n",
          '[strict]',
          "--option1 <some-option-description> [required]",
       )
    ) || exit(1);
    
4

2 に答える 2

3
Readonly my $ARGS => Getopt::Declare->new(
# ...
);
$ARGS or exit(1);

同様に動作するはずです。

于 2013-08-02T14:37:47.570 に答える
1

@chorobaが示唆したように、当面の問題は優先事項の1つです。

読み取り専用 $v => ... または死ぬ; # この構造...
読み取り専用 (my $v, ...) または死ぬ; #本当にこれ…
私の$v、「読み取り専用」、...または死ぬ; # これは多かれ少なかれこれであり、これは ... に評価されます  
ReadOnly::Scalar=SCALAR(0x123)または死ぬ; #tie() の下
のオブジェクト...

orしたがって、返されたオブジェクトが true と評価されるため、の右半分にヒットすることはありません。

さて、本当にその構文を使い続けたいのであれば、次のようにして、基になるオブジェクトではなく、tie()d 変数を強制的に使用することができます。

use Readonly ();
sub MakeReadonly(\[$@%]@) {
  &Readonly::Readonly;               # tie() ${$_[0]} to Readonly implementation
  ${$_[0]};                          # ... but return the tied variable, not the object
}

....

MakeReadonly my $e => ... or die;    # This ...
MakeReadonly(my $e, ...)  or die;    # becomes this ...
$e or die;                           # which is effectively this.

余談ですが、この構成には注意することをお勧めします。の魅力はReadonly、あたかもこれを行っているかのように、属性付きスカラーへの代入に一見似た構文を使用できることです。

my $v : Readonly = something() or die;    # XXX Doesn't work!  Not even Attribute::Constant
                                          # works like this, unfortunately.

…が、かなり違います。投稿のタイトルと本文の言い回しは、少なくとも最初はこのように考えていたことを示しています。(たとえば、「読み取り専用変数が true に評価されます」-まあ、それらの基になるオブジェクトはそうしますが、結ばれた変数自体はそうではないかもしれません。または、「割り当て前に評価されます」-まあ、実際にはそれ自体を割り当てているわけではありませんが、再び tie( )ing.)

于 2013-08-02T13:55:52.683 に答える