この記事は、Perl Advent Calendar 2024 5日目の記事(穴埋め)です。 4日目は@shogo82148で「Perl 5.40でtry/catch機能が安定版になりました」でした。
Perl 5.40.0 から、真偽値の排他的論理和を表す ^^
演算子が導入されました。
背景
Perl には「コンテキスト(文脈)」と呼ばれる概念があります。 Perlはプログラム内の文脈によって、今扱っているデータをどんな種類(数値なのか文字列なのか)で解釈するかを決定します。
たとえば $x + $y
は数値加算の演算子であり、$x
や $y
は数値コンテキストで解釈されます。
数値コンテキストではデータは数値として評価されます。
もし $x
や $y
に文字列が入っていた場合は、一度数値に変換してから演算が行われます。
そして、Perlにはコンテキスト毎に異なった演算子が存在します。 たとえば、「論理積」を表す演算子の場合、 「整数の論理積」「文字列の論理積」「真偽値の論理積(優先度高)」「真偽値の論理積(優先度低)」の4種類の演算子があります。 「論理和」や「排他的論理和」を加えて表にまとめてみると以下のようになります。
コンテキスト | 論理積 | 論理和 | 排他的論理和 |
---|---|---|---|
数値 | & |
| |
^ |
文字列 | &. |
|. |
^. |
真偽値(優先度高) | && |
|| |
|
真偽値(優先度低) | and |
or |
xor |
さて、この表をよく見ると「真偽値の排他的論理和」の部分にひとつだけ空白があります。
「この空白を埋めよう!」というモチベーションで追加されたのが ^^
演算子です。
^^
は両辺の真偽値コンテキストで評価し、その排他的論理和を計算します。
試してみた
実際に試してみました。
use v5.40;
sub say_bool($v) {
say $v ? "true" : "false";
}
say_bool false ^^ false;
say_bool false ^^ true;
say_bool true ^^ false;
say_bool true ^^ true;
Perl 5.40 で実行してみると、真理値表通りの結果が得られましたね。
false
true
true
false
xor演算子との違いは?
xor
演算子と ^^
演算子の違いは優先順位です。
たとえば以下のコードは (say_bool false) xor false;
と解釈されてしまって、
期待したとおりには動きません。
use v5.40;
sub say_bool($v) {
say $v ? "true" : "false";
}
say_bool false xor false;
say_bool false xor true;
say_bool true xor false;
say_bool true xor true;
Useless use of logical xor in void context at xor-legacy.pl line 7.
Useless use of logical xor in void context at xor-legacy.pl line 8.
Useless use of logical xor in void context at xor-legacy.pl line 9.
Useless use of logical xor in void context at xor-legacy.pl line 10.
false
false
true
true
正しく動作させるにはカッコを補う必要があります。
use v5.40;
sub say_bool($v) {
say $v ? "true" : "false";
}
say_bool(false xor false);
say_bool(false xor true);
say_bool( true xor false);
say_bool( true xor true);
短絡評価(ショートサーキット)は機能するの?
排他的論理和に短絡評価(ショートサーキット)は機能するのでしょうか? 先に結論を書いておくとしません。
論理積、論理和の演算子は短絡評価をします。
たとえば、以下のコードで関数 g
は評価されず、実行されません。
say_bool false && g();
&&
の左被演算子が false
なので、右被演算子を評価するまでもなく、結果が false
だとわかるからです。
排他的論理和(^^
)の場合はどうでしょう?
簡単なプログラムを書いて検証してみました。
use 5.40.0;
use utf8;
use Encode;
sub say_bool($v) {
say $v ? "true" : "false";
}
sub f($v) {
say encode_utf8("fが評価されました");
return $v;
}
sub g($v) {
say encode_utf8("gが評価されました");
return $v;
}
say_bool f(false) ^^ g(false);
say_bool f(false) ^^ g( true);
say_bool f( true) ^^ g(false);
say_bool f( true) ^^ g( true);
実行してみると、毎回すべての被演算子が評価されている様子を確認できます。
fが評価されました
gが評価されました
false
fが評価されました
gが評価されました
true
fが評価されました
gが評価されました
true
fが評価されました
gが評価されました
false
左被演算子の情報だけでは最終結果が決定しないので、このような結果になるんですね。
まとめ
Perl 5.40.0 から、真偽値の排他的論理和を表す ^^
演算子が導入されました。
&&
, ||
の排他的論理和バージョンで、優先度の高い xor
演算子として動作します。
実際有用な場面が思いつかない。
Perlの世界に新たな光、
XOR^^
が登場するよ、
論理は明確、日々の道、
コードを簡潔にするための手助け。
一つの真実、二つの心、
^^
でコードはきれいに整う。
🐇✨by CodeRabbit
明日6日目は@MacOlinで「JSON::PPのencodeメソッドと日本語とutf8」です。 お楽しみに!