読者です 読者をやめる 読者になる 読者になる

Perl日記

PerlとかRubyとかPHPとかPythonとか

配列への論理和代入での注意

ちょっと悩んだのでメモ。
あるメソッドにおいて、引数を全部配列に入れる、ただし引数がなかったらデフォルトのリストを配列に入れる、ということをしたかった。

sub my_method {
  my ($self, @list) = @_;
  @list ||= @DEFAULT;
…
}

しかしこれはエラーで怒られる。

Can't modify private array in logical or assignment (||=) at - line 3, near "@DEFAULT;"

一見問題ないように思える。だって

@list ||= @DEFAULT;

は、

@list = @list || @DEFAULT;

のことだし、と思って、よく考えたら
スカラコンテキストが持続しているのだということに気がついた。
つまり

@list ||= @DEFAULT;
# ↑ スカラコンテキストでbooleanが決まる
# ↓ ゆえにこうなって
scalar(@list) ||= @DEFAULT;
# ↓ こうなる
scalar(@list) = scalar(@list) || @DEFAULT;

という感じだと思う。
scalar(@list) に値は代入できないのでエラー、みたいな。


perlopにはなかった。