※ gem化しました → Rubyのクラス階層やメソッドを美しく表示する、rubywho
※githubに登録しました。→ p_classtree、改良(2)
これは何?
gem等で提供されている開発中のライブラリを自分で使うような場合、ドキュメントが整備中だったり、ドキュメントに載ってない新しい機能が入っていることはよくあります。そのような時はまあソースを読むしかないのですが、そもそもチュートリアルに沿って動かしたあのインスタンスがなんだったのか分からなくて、スタート地点すら分からずに途方にくれることが良くあります(C++等の静的言語と違い、そもそもソースコード中に型を類推する手がかりが少ないというのもあります)。Rubyにはインスタンスの所属するクラスや、そのメソッドを調べる方法が用意されているので、ざっとクラス階層とpublicなメソッド群を調べる関数を作ってみました。
p_classtreeという関数にオブジェクトやクラスを渡すと・・。
# インスタンスを渡した場合はその所属するクラスの階層、メソッドを表示 a = [0, 1, 2] p_classtree(a) puts # クラス名を直接渡してもOK p_classtree(Hash)
結果はこんな感じで表示されます。
Array | &, *, +, -, <<, | <=>, ==, [], []=, abbrev, | assoc, at, choice, clear, collect, | collect!, combination, compact, compact!, concat, | count, cycle, delete, delete_at, delete_if, | drop, drop_while, each, each_index, empty?, | eql?, fetch, fill, find_index, first, | flatten, flatten!, frozen?, hash, include?, | index, indexes, indices, insert, inspect, | join, last, length, map, map!, | nitems, pack, permutation, pop, product, | push, rassoc, reject, reject!, replace, | reverse, reverse!, reverse_each, rindex, select, | shift, shuffle, shuffle!, size, slice, | slice!, sort, sort!, taguri, taguri=, | take, take_while, to_a, to_ary, to_s, | to_yaml, transpose, uniq, uniq!, unshift, ↓ values_at, yaml_initialize, zip, |, Object Fixnum | %, &, *, **, +, | -, -@, /, <, <<, | <=, <=>, ==, >, >=, | >>, [], ^, abs, div, | divmod, even?, fdiv, id2name, modulo, | odd?, quo, size, to_f, to_s, ↓ to_sym, zero?, |, ~, Integer | ceil, chr, downto, even?, floor, | integer?, next, odd?, ord, pred, | round, succ, times, to_i, to_int, ↓ truncate, upto, Numeric | +@, -@, <=>, abs, ceil, | coerce, div, divmod, eql?, fdiv, | floor, integer?, modulo, nonzero?, quo, | remainder, round, singleton_method_added, step, to_int, ↓ truncate, zero?, Object
ちなみに最近良く触ってるrroongaオブジェクトを表示するとこんな感じ。
Groonga::Hash ↓ search, Groonga::Table | [], clear_lock, column, column_value, columns, | define_column, define_index_column, delete, difference!, each, | empty?, group, have_column?, inspect, intersection!, | lock, locked?, merge!, open_cursor, paginate, | records, select, set_column_value, set_value, size, | sort, support_sub_records?, truncate, union!, unlock, ↓ value, Groonga::Object | ==, [], []=, append, close, | closed?, context, domain, id, inspect, | name, path, persistent?, prepend, range, ↓ remove, temporary?, Object
ソース
def p_classtree(c) unless c.is_a?(Class) c = c.class end while (true) puts c.name break if (c == Object) p_classtree_sub(c) c = c.superclass end end def p_classtree_sub(c) array = c.public_instance_methods(false).sort if (array.size > 5) print "| " else print "↓ " end counter = 0 array.each_with_index do |v, index| print v + ", " counter += 1 if (counter >= 5) counter = 0 puts if (array.size - index > 5) print "| " else print "↓ " end end end puts end
課題
今はasciiコード順にソートしちゃってるけど、本当は'abs'みたいなアルファベット系と、'[]' みたいな演算子系は分けて表示したい所。いい方法無いかなあ?
↓みたいになったら素敵!
Fixnum | abs, div, divmod, even?, fdiv, | id2name, modulo, odd?, quo, size, | to_f, to_s, to_sym, zero?, | %, &, *, **, +, -, | -@, /, <, <<, <=, | <=>, ==, >, >=, >>, ↓ [], ^, |, ~,