"Smart Match(~~)" を使用して Perl コードをテストしているときに、この問題に直面しました。42、42.0、「42.0」、「42」の間に違いはありますか
$var1 = "42";
$var2 = "42.0";
$a = $var1 ~~ $var2;
私は$a
0になっています。つまり$var1
、 と$var2
は等しくありません。
説明してください。
"Smart Match(~~)" を使用して Perl コードをテストしているときに、この問題に直面しました。42、42.0、「42.0」、「42」の間に違いはありますか
$var1 = "42";
$var2 = "42.0";
$a = $var1 ~~ $var2;
私は$a
0になっています。つまり$var1
、 と$var2
は等しくありません。
説明してください。
スマートマッチ演算子は、「通常、あなたが望むことをします」。「いつもではない」とお読みください。
42 ~~ 42.0
true を返します。
42 ~~ "42.0"
も true を返します。文字列は数値と比較されるため、数値として認識されます。についても同様です"42" ~~ 42.0
。
"42" ~~ "42.0"
false を返します: 両方の引数が文字列であり、これらの文字列は「等しい」として比較されませんが、数値的な意味は「等しい」と見なされます。"two" ~~ "two-point-oh"
Perl に真と見なされたくないでしょう。
ゼロを追加することで、文字列を強制的に数値として解釈することができます。
0+"42" ~~ "42.0"
最初の文字列が number に強制され、2 番目の文字列がそれに続くため、再び true を返します42
。
perldoc perlsyn
またはperldoc perlop
ページは、スマート マッチングの仕組みを定義します。
Object Any invokes ~~ overloading on $object, or falls back:
Any Num numeric equality $a == $b
Num numish[4] numeric equality $a == $b
undef Any undefined !defined($b)
Any Any string equality $a eq $b
文字列の等価性がデフォルトであることがわかります。
今のところ、スマート マッチの使用を再検討することをお勧めします。現在の実装は、とりわけあなたの質問と amon の回答のために、Perl コミュニティによって間違いであると見なされています。
Perl の次のメジャー リリース (5.18) に含まれる可能性がある、「より健全な」シンプルで互換性のないバージョンのスマート マッチの作業が進行中です。$b が単純なスカラー値 (42 や "42" など) の場合、 $a ~~ $b は許可されません。
時間に余裕がある場合は、Perl5 ポーターのアーカイブ (このスレッドなど) を参照できます。
コンテキストタイピング。
$Var1
最後に$Var2
(代入で) 文字列として使用されたため、文字列として動作するようになりました。~~
両方の引数が文字列の場合、文字列比較を行います。
それらの 1 つを数値として使用すると (それに代入する必要さえありません)、数値として動作し~~
、数値比較が使用されます。
このスクリプトは以下を出力しますNO YES
:
my $v1 = "42";
my $v2 = "42.0";
print (($v1 ~~ $v2) ? 'YES ' : 'NO ');
$v1 + 0;
print (($v1 ~~ $v2) ? 'YES ' : 'NO ');