前回の記事「Ruby、君のオブジェクトはなんて呼び出せばいいの?」で、Rubyには大量のメソッドがあることが分かりました。今回はその補足として、各クラスごとのメソッド数を数えてグラフ化してみます。

インスタンスメソッドを数える

まずは、インスタンスメソッドを数えましょう。グラフ化の対象は、10以上のメソッドを持つクラスです。最初にクラスごとのメソッド数をリストアップします。

klasses = ObjectSpace.each_object(Module)

def live(methods)
  methods.reject { |m| "#{m}".start_with? '_deprecated' }
end

methods = klasses.map do |k|
  [k, live(k.methods(false)).size, live(k.instance_methods(false)).size]
end

# List of Instance Methods
ims = methods.map { |k, cm, im| [k, im] }.reject { |k, m| m < 10 }.sort_by { |k, m| -m }

puts ims.map { |kim| kim.join(" => ") }.join(", ")

結果は次のようになりました。

String => 109, Pathname => 92, Array => 88, IO => 70, Time => 54, Hash => 53, ARGF.class => 51, Kernel => 48, Enumerable => 47, Module => 43, Float => 42, File::Stat => 42, Numeric => 41, Complex => 37, Bignum => 36, Fixnum => 34, Thread => 25, Rational => 25, Integer => 24, Symbol => 24, MatchData => 19, Range => 18, Proc => 17, Regexp => 16, Struct => 16, Method => 16, Process::Status => 15, Encoding::Converter => 14, NilClass => 12, Enumerator => 12, UnboundMethod => 12, File => 11, Dir => 11

なるほど、Stringのインスタンスメソッドは100を超えてるんですね!あれ、なんでPathnameがいるのかな…理由は分かりませんが、メソッド多いですねー。そして、Array, IO, Time, Hashと続きます。

さあ、次にこれをGoogle Chart APIでグラフ化します。

x, data = ims.transpose
y = 0.step(110, 10).to_a

puts Gchart.bar(:data => data,
             :max_value => 110,
             :axis_with_labels => 't,y,x',
             :axis_labels => [y, x.reverse, y],
             :size => '390x760',
             :bar_width_and_spacing => 17,
             :title => 'Instance Methods',
             :bg => 'efefdd',
             :orientation => 'horizontal',
             )

#>> http://chart.apis.google.com/chart?chxl=0:|0|10|20|30|40|50|60|70|80|90|100|110|1:|Dir|File|UnboundMethod|Enumerator|NilClass|Encoding%3A%3AConverter|Process%3A%3AStatus|Method|Struct|Regexp|Proc|Range|MatchData|Symbol|Integer|Rational|Thread|Fixnum|Bignum|Complex|Numeric|File%3A%3AStat|Float|Module|Enumerable|Kernel|ARGF.class|Hash|Time|IO|Array|Pathname|String|2:|0|10|20|30|40|50|60|70|80|90|100|110&chxt=t,y,x&chbh=17&chf=bg,s,efefdd&chd=s:9zxnedcbaYXXXUUTOONNKKJJJJIHGGGGG&chtt=Instance+Methods&cht=bhs&chs=390x760&chxr=0,109,110

前回同様、Google Chart APIを使って、次のグラフが得られました。

instance methods noshadow

個人的には、Symbolのメソッド数が少ないな、という印象です。

クラスメソッドを数える

次に、クラスメソッドを数えましょう。グラフ化の対象は、5以上のメソッドを持つクラスです。最初にクラスごとのメソッド数をリストアップします。

# List of Class Methods
cms = methods.map { |k, cm, im| [k, cm] }.reject { |k, m| m < 5 }.sort_by { |k, m| -m }

puts cms.map { |kcm| kcm.join(" => ") }.join(", ")

結果は次のようになりました。

Gem => 89, Kernel => 59, File => 57, Process => 39, FileTest => 26, Math => 26, Dir => 16, Process::Sys => 15, IO => 15, Thread => 13, Encoding => 11, Process::UID => 9, Process::GID => 9, GC::Profiler => 7, GC => 7, Time => 7, RubyVM::InstructionSequence => 7, ObjectSpace => 6, Regexp => 6

Gemは組み込みライブラリではないので、除外すべきだったのかもしれませんが、まあ兎に角、ダントツ1位です^ ^; Kernelはそのメソッドがモジュール関数になっているので多いのですね。従って、実質1位はFileと言っていいんじゃないでしょうか。

さあ、次にこれをGoogle Chart APIでグラフ化します。

x, data = cms.transpose
y = 0.step(90, 10).to_a

puts Gchart.bar(:data => data,
             :max_value => 90,
             :axis_with_labels => 't,y,x',
             :axis_labels => [y, x.reverse, y],
             :size => '600x500',
             :bar_width_and_spacing => 18,
             :title => 'Class Methods',
             :bg => 'efefdd',
             :orientation => 'horizontal',
             )

#>> http://chart.apis.google.com/chart?chxl=0:|0|10|20|30|40|50|60|70|80|90|1:|Regexp|ObjectSpace|RubyVM%3A%3AInstructionSequence|Time|GC|GC%3A%3AProfiler|Process%3A%3AGID|Process%3A%3AUID|Encoding|Thread|IO|Process%3A%3ASys|Dir|Math|FileTest|Process|File|Kernel|Gem|2:|0|10|20|30|40|50|60|70|80|90&chxt=t,y,x&chbh=18&chf=bg,s,efefdd&chd=s:9onaRRLKKIHGGEEEEEE&chtt=Class+Methods&cht=bhs&chs=600x500&chxr=0,89,90

結果は次の通り。

class methods noshadow

5以下のメソッドを削ってますが、ロングテールといった感じでしょうか。まあ、あまり感想はありません..

Wordleによるビジュアライゼーション

さて、実は今回はここからが本題です。

クラスごとにメソッドをグラフ化しても面白みがないことが分かったので、以前に紹介したWordle - Beautiful Word Cloudsを使って、Rubyのクラスごとのメソッド数をビジュアライズしてみたいと思います。Wordleはテキスト中の単語をその出現頻度から重み付けしてサイズを決定し、グラフィカルに配置して表示するツール/サービスです。このブログでも以前に2回ほど紹介しました。

Rubyで英文小説をWordleしようよ

Wordleでビジネスカードを作ろう!

Wordleではテキストを渡して画像を生成させるのが基本ですが、単語とその重み付けの情報を渡して画像を生成する方法も提供されています。今回はこれを使って、Rubyにおける各クラス名をそのメソッド数で重み付けして画像を生成してみたいと思います。

まずは重み付けの情報を作ります。インスタンスメソッドから。

# Instance methods for Wordle
puts ims.map { |k, m| "#{k}:#{m}" }

次のようなデータが得られます。

String:109
Pathname:92
Array:88
IO:70
Time:54
Hash:53
ARGF.class:51
Kernel:48
Enumerable:47
Module:43
Float:42
File::Stat:42
Numeric:41
Complex:37
Bignum:36
Fixnum:34
Thread:25
Rational:25
Integer:24
Symbol:24
MatchData:19
Range:18
Proc:17
Regexp:16
Struct:16
Method:16
Process::Status:15
Encoding::Converter:14
NilClass:12
Enumerator:12
UnboundMethod:12
File:11
Dir:11

クラスメソッドも同様にします。

# Class methods for Wordle
puts cms.map { |k, m| "#{k}:#{m}" }

出力です。

Gem:89
Kernel:59
File:57
Process:39
FileTest:26
Math:26
Dir:16
Process::Sys:15
IO:15
Thread:13
Encoding:11
Process::UID:9
Process::GID:9
GC::Profiler:7
GC:7
Time:7
RubyVM::InstructionSequence:7
ObjectSpace:6
Regexp:6

WordleのAdvancedタブを開いて、Paste weighted words or phrases here:に出力データを貼り付けます。そしてGoボタンを押せば自動でWordle画像が生成されます。後は、Randomizeボタンを押すなり、そのFont, Layout, Colorを変更するなりして、お好みを作り上げます。

こうして生成された画像が以下になります。

Ruby Classes emphasized with Number of Instance Methods

instance methods noshadow

Ruby Classes emphasized with Number of Class Methods

Alt title noshadow noshadow

Cool!なかなかカッコイイでしょ?

時間が許すなら、みなさんもこのブログのデータをコピーして、Wordleしてみてください。楽しめると思います。

というわけで、Ruby大学におきましては、Stringクラスの生徒(Class Mates)たちと、新人先生Gem君が太ってるってことが分かりましたよ!

Ruby Methods Analysis — Gist


Wordle: Ruby Instance Methods noshadow

Wordle: Ruby Class Methods noshadow


まんが クラスメイトは外国人 -多文化共生20の物語- by みなみ ななみ



blog comments powered by Disqus
ruby_pack8

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