メグ「ねえ、[1,2,3]みたいな配列オブジェクトに対して呼び出せるメソッドの数って、いくつくらいあるの?」

るびお「えっ?そんなのirb叩いてRubyに聞けば直ぐわかるじゃん。こうだよ。」

irb> [1,2,3].methods.size
=> 167

るびお「配列オブジェクトはArrayクラスのインスタンスだから、こうしてもいいんだよ。」

irb> [1,2,3].class
=> Array
irb> Array.instance_methods.size
=> 167

メグ「167個もあるの。じゃあ、それが全部Arrayに定義されてるのね?」

るびお「あーそれはね、そうじゃないんだよ。Arrayに定義されてる分を知りたいときは、引数にfalseを渡すんだ。」

irb> Array.instance_methods(false).size
=> 89

メグ「そうなの。じゃあ、残りはどこから来てるの?」

るびお「うん。いい質問だね。それはね、Arrayの祖先から来てるんだよ。祖先が誰かって?それもRubyが教えてくれるよ。ほら。」

irb> Array.ancestors
=> [Array, Enumerable, Object, Kernel, BasicObject]

メグ「るびお君素敵!じゃあ、これらの祖先に定義されたインスタンスメソッドとArrayに定義されたインスタンスメソッドを合わせれば、167個になるのね!」

るびお「そうさ。メグは飲み込みが早いなあ。じゃあ、早速数えてみよう。ほら。」

irb> e = Enumerable.instance_methods(false).size
=> 48
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> a = Array.instance_methods(false).size
=> 89
irb> e + o + k + bo + a
=> 191

るびお「げっ!」

メグ「るびお君の嘘つき!191個もあるじゃない。24個はどこに消えたのよ!」

るびお「…」



メグ「るびお君、あなたまだまだね。オーバーライド分があるじゃないのよ。Arrayで継承元のメソッドが再定義されてたら、その分は差し引かなきゃ。なんで気が付かないかなあ。じゃあ、論理和してみるわよ。」

irb> Array.ancestors.map{|klass| klass.instance_methods(false)}.inject{|mem,klass| mem | klass }.size
=> 167

るびお「…」



(追記:2013-08-28) 続きを書きました。

Rubyのメソッドをもう一度、数えましょう♫



blog comments powered by Disqus
ruby_pack8

100円〜で好評発売中!
M'ELBORNE BOOKS