case文やif文で型を比較したときの挙動

oscモジュールのソースを見ていて不思議なコードがあり、ちょっと仕様から調べてみた。
そのコードとはcase-whenで自動的に型を判別してくれる、というものなのだ。
それに関連していろいろテストしてみたらなかなか面白い挙動になったのでメモしておく。

case文で型による分岐

test_params = [ 99, 1024, 3.14, "apple", nil ]
test_params.each do |param|
    case param
    when 99
        p "#{param}"
    when Integer
        p "Integer .. #{param}"
    when Float
        p "Float   .. #{param}"
    when String
        p "String  .. #{param}"
    else
        p "#{param.class} .. #{param}"
    end
end

上記コードの出力は以下のようになる。

"99"
"Integer .. 1024"
"Float   .. 3.14"
"String  .. apple"
"NilClass .. "

で、ポイントは、数値の分岐です。
まず、rubyにおける数値のクラス構成は「Rubyの数値 - octech」←こんな感じになっている。つまり、Fixnum < Integer < Numeric という派生関係だ。
これに関してこんなコードを実行してみた。

p "1024.class is #{1024.class}"
case 1024
when Numeric
    p "Case-statement detects Numeric."
end
case 1024
when Integer
    p "Case-statement detects Integer."
end
case 1024
when Fixnum
    p "Case-statement detects Fixnum."
end

結果は次のようになる。

"1024.class is Fixnum"
"Case-statement detects Numeric."
"Case-statement detects Integer."
"Case-statement detects Fixnum."

つまり、case文による分岐は、派生元のスーパークラスの型でも比較がなされている、ということだ。

if文の場合

では、if文で class メソッドによる比較を行ったときはどうなるのか?と以下のコードを試してみた。

# if文ではどうなるか?
if 1024.class == Numeric then
    p "If-statement detects Numeric"
end
if 1024.class == Integer then
    p "If-statement detects Integer"
end
if 1024.class == Fixnum then
    p "If-statement detects Fixnum"
end

結果は次のようになる。

"If-statement detects Fixnum"

if文で、classメソッドによる比較を行ったときには、きっちり同じクラスでないとダメなようだ。
ということで、次の疑問が残った。
「case文におけるクラス比較のように、スーパークラスまでみて比較する方法は何かあるのだろうか?」