― Web Technology and Life ―

Perl演算子「||」,「or」の罠

2012-03-11
最近、リストと配列(Array)はPerlでは別物ってtogetterがあがりましたが、別件ですが、そういやこの「||」と「or」の違いで、はまったなーということで久しぶりに「罠」ネタをメモっておきます。

はまったコード

なにげなく、

my $aaa = logic_a(
     hogehoge => 1,
     mogemoge => 2,
) or die;

ってかいてあったものに、まぁ、dieする前に、別のロジックをつけてもいいよなーと思って

my $aaa =logic_a(
     hogehoge => 1,
     mogemoge => 2,
) or logic_b(
     hogehoge => 1,
     mogemoge => 2,
) or die;

ってかいてしまった。なんか、「or」演算子が並んでいて「キレイ」なコードだと思ったんですね。それで、これでいいやーと思ったんです。

想定していたこのコードの挙動は、logic_aがundefかえしたときに、logic_bの結果が$aaaに入るということだったんだけど、 残念ながら、実際の挙動は、logic_bは実行されるけど、$aaaにはundefが入ってしまうのでした。

学んだこと

要するに、

  • 「or」演算子は代入演算子ではないので結果が返らない
  • 「||」演算子は代入演算子なので結果が変える

ということだったのです。(と勝手に思い込みましたが嘘です、書きに追記あり)

結局同じ演算子が並んでいて「キレイ」ということは忘れてこうした。

my $aaa =logic_a(
     hogehoge => 1,
     mogemoge => 2,
) || logic_b(
     hogehoge => 1,
     mogemoge => 2,
) or die;

「|| die」にしてもいいんだけど、or dieのほうが好きだし、dieの結果は返さない(返らない)から、 結果的には、このコードがPerlの仕様的にもキレイだと思います。

【追記:2012-03-11 17:42】orと||の違いは結合の強度(演算子の優先順位)

上述まで書いてアップしたTwitterとかはてぶで、「違うよ」って趣旨のコメントを発見して感激+感謝です。(また、上述を読んで勘違いした人すみません。)

gfxさんに、「 orと||の違いは結合の強度(演算子の優先順位)ですね」と教えて頂きました。「or」演算子でも結果が返るですね。。。(参考;『perlop - Perl の演算子と優先順位 【perldoc.jp】』)だから、orを続けても、()をつけて演算子の優先順位を下げてやれば想定通りに動くということです。下記がそのコード。


my $aaa =(
    logic_a(
         hogehoge => 1,
         mogemoge => 2,
    ) or logic_b(
         hogehoge => 1,
         mogemoge => 2,
    )
) or die;

つづけざまに『Perlのクロージャーの罠』も書きました。これまた、ソーシャルメディアでコメント頂きましたー。

Perl update_at : 2012-03-11T17:41:41
hirobanex.netの更新情報の取得
 RSSリーダーで購読する   
blog comments powered by Disqus