"Smart Match(~~)" を使用して Perl コードをテストしているときに、この問題に直面しました。42、42.0、「42.0」、「42」の間に違いはありますか
$var1 = "42";
$var2 = "42.0";
$a = $var1 ~~ $var2;
私は$a0になっています。つまり$var1、 と$var2は等しくありません。
説明してください。
"Smart Match(~~)" を使用して Perl コードをテストしているときに、この問題に直面しました。42、42.0、「42.0」、「42」の間に違いはありますか
$var1 = "42";
$var2 = "42.0";
$a = $var1 ~~ $var2;
私は$a0になっています。つまり$var1、 と$var2は等しくありません。
説明してください。
スマートマッチ演算子は、「通常、あなたが望むことをします」。「いつもではない」とお読みください。
42 ~~ 42.0true を返します。
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 ');