Rubyのメソッドをもう一度、数えましょう♫
「Rubyのメソッドを数えましょう♫」の続きです…
メグ「ねえ、配列オブジェクトのメソッド数については分かったから、こんどはArrayクラス自身のメソッドについて教えてくれる?」
るびお「…えっ?あぁ…。」
メグ「じゃあ、Arrayクラスに対して呼び出せるメソッドの数って、いくつあるのかな?」
るびお「えっ?同じようにirb
を叩けばいいと思うんだけど…。」
irb> Array.methods.size
=> 97
るびお「ArrayクラスはClassクラスのインスタンスだから、こうしてもいいんだよ。」
irb> Array.class
=> Class
irb> Class.instance_methods.size
=> 95
るびお「げっ!」
メグ「るびお君の嘘つき!95個に減っちゃったじゃない。2個はどこに消えたのよ!」
るびお「…」
メグ「るびお君、やっぱりまだまだね。シングルトンメソッドがあるじゃないのよ。Arrayクラスで自身のために定義されてるメソッドのことよ。なんで気が付かないかなあ。じゃあ、引数にfalseを渡すか、singleton_methodsしてみて。」
irb> Array.methods.size
=> 97
irb> Array.methods(false).size
=> 2
irb> Array.singleton_methods
=> [:[], :try_convert]
るびお「…」
メグ「気を取り直して。じゃあ、Arrayで呼べる97個のメソッドのうち95個はClassに定義されてるって理解でいいの?」
るびお「引数にfalseを渡すの知ってるのに…。」
irb> Class.instance_methods(false).size
=> 3
irb> Class.instance_methods(false)
=> [:allocate, :new, :superclass]
メグ「へぇ。Classクラスには3個しかメソッド無いんだ。じゃあ、残りはどこから来てるの?」
るびお「明らかに意地悪してるよね?まあいいけど。Classの祖先を調べてよ。」
irb> Class.ancestors
=> [Class, Module, Object, Kernel, BasicObject]
メグ「るびお君素敵!Classクラスって継承ツリーのルートじゃ無いんだ。ClassクラスのスーパークラスってModuleクラスなんだー。しかもこれらにはさっきの3つのメソッドの差しかないし。じゃあ、これらの祖先に定義されたインスタンスメソッドとClassクラスに定義されたインスタンスメソッドを合わせれば、95個になるのね!私やってみる!」
irb> m = Module.instance_methods(false).size
=> 44
irb> o = Object.instance_methods(false).size
=> 0
irb> k = Kernel.instance_methods(false).size
=> 46
irb> bo = BasicObject.instance_methods(false).size
=> 8
irb> c = Class.instance_methods(false).size
=> 3
irb> m + o + k + bo + c
=> 101
メグ「あっ、数が合わない!」
るびお「あのさぁ…。いい加減にしてよ。」
メグ「オーバーライド分引かなきゃ。論理和すればいいんだったわね。ふふっ。」
irb> Class.ancestors.map{|klass| klass.instance_methods(false)}.inject{|mem, klass| mem | klass }.size
=> 95
メグ「正解!」
るびお「…」
blog comments powered by Disqus