文字列と数値の比較
文字列と数値を比較しようとした場合に、Ruby ではエラーになり PHP ではエラーにならない。他のプログラミング言語ではどちらの動作になるのだろうと、先日コードを書いていて疑問に思ったので調べてみることにした。調べた言語は動的型言語ばかりを五つほど。理由は今の環境で動かせるのがその五つだったので。
結果
PHP
<?php $str = "100"; $int = 20; echo $str > $int ? $str : $int, "\n"; # => 100 ?>
Ruby
str = "100" int = 20 puts str > int ? str : int # => `>': comparison of String with 20 failed (ArgumentError)
Perl
my $str = "100"; my $int = 20; print $str > $int ? $str : $int, "\n"; # => 100
Python
str = "100" int = 20 print str if str > int else int # => 100
JavaScript
var str = "100"; var num = 20; alert(str > num ? str : num); // => 100
まとめ
Ruby 以外は数値としての比較が行われた。Ruby 以外は ">" は比較演算子に分類されるが、 Ruby ではメソッドに分類されていて、オーバーライドも可能なので、文字列と数値の比較でもエラーにならないようにすることができる。例えばこんな感じに。
class String def >(var) self.to_i > var.to_i end end str = "100" int = 20 puts str > int ? str : int # => 100
でも、文字列 > 数値 の場合はこれでいいけど、数値 > 文字列 の場合も動作させようとすると、Integer (Numeric) の > メソッドもオーバーライドしなくてはいけなくなる。じゃあ、他のクラスとの比較だったらってことを考えるときりがない。こんなことしてもいいことなさそう。素直に to_i を呼ぶべきだね。
余談だけど、今回 Python のコードを初めて書いた。三項演算子が他の言語と違って、条件分が真ん中にくるんだね。