TrueClass | FalseClass の親クラスBoolClass(仮)が欲しい! on Ruby
Rubyではtrue・falseは別クラスで
TrueClass < Object < Kernel (< BasicObject) FalseClass < Object < Kernel (< BasicObject)
という継承になっています。
このため、オブジェクトにtrue、falseのどちらかが入ってきているかを
チェックしたい場合
if object.eql?(true) || object.eql?(false) then ... end
あるいは
if object.kind_of?(TrueClass) || object.kind_of?(FalseClass) then ... end
のように書くことになります。
(true・falseは夫々TrueClass・FalseClassのシングルトンインスタンス(唯一のインスタンス))
TrueClass | FalseClass の親クラスBoolClass(仮)があると
TrueClass < BoolClass(仮) < Object < Kernel (< BasicObject) FalseClass < BoolClass(仮) < Object < Kernel (< BasicObject)
という継承となり、上記のチェックは次のようにも書けるようになります。
if object.kind_of?(BoolClass(仮)) then ... end
true、falseが別のクラスになっている仕様は今更変えられないと思います。
TrueClass、FalseClass の親クラスBoolClass(仮)を導入すると
true、falseがあたかも同一のクラスであるかのように
扱えるようになります。
BoolClass(仮))はクラスではなくモジュールでも良い(はず)です。
[追記]
ruby 1.9.1p0 (2009-01-30 revision 21907) on MacOSX10.5.7(C2D 2.4GHz)で
tt = "test" start_time = Time.new.to_f if ps.kind_of?(TrueClass) || ps.kind_of?(FalseClass) then puts "test" end end_time = Time.new.to_f puts '' + (end_time - start_time).to_s + ' sec' start_time = Time.new.to_f if tt.eql?(true) || tt.eql?(false) then puts "test" end end_time = Time.new.to_f puts '' + (end_time - start_time).to_s + ' sec'
を数回試行したところ、eql?がkind_of?よりも性能的に良いです。
どちらもeの-6乗 秒のオーダーで、kind_of?がeql?の
1〜3倍くらいの処理時間となっていました。
###
#トラックバック元http://d.hatena.ne.jp/mr_konn/20090609/1244526908
#に書かれているRuby組込みのKernelモジュールもしくはObjectクラスに後付で
#メソッドを追加する案は個人的には却下、boolかどうかを判定するために
#(全てのオブジェクトに影響を与える)KernelモジュールもしくはObjectクラスを
#いじるのはいただけない。
#(nilはNULLポインタを指すので)Object#nil?が在ることに疑問はない、
#Object#bool?は個人的にはありえない。
#
#それなら、bool用ユーティリティ(ヘルパー?)クラスBoolUtilを作成してBoolUtil#bool?
#(クラスメソッド)とするほうが良いように思う。(若干、コーディング量は多くなる
#けれど。)(Object用ユーティリティ(ヘルパー?)クラスObjectUtilでも可。)
#
#class BoolUtil
# def self.bool?(obj)
# obj.eql?(true) || obj.eql?(false)
# end
# ・・・
#end
#
#bool?メソッドのロジックは各人お好きなように。
#