文字列と数値の比較

文字列と数値を比較しようとした場合に、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 のコードを初めて書いた。三項演算子が他の言語と違って、条件分が真ん中にくるんだね。