Rubyでメソッドの定義してあるファイルを知る方法
- 2012/10/15 (Mon) |
- ruby |
- CM(0) |
- Edit |
- ▲Top
Ruby-talk ML で便利な技を教えてもらったので忘れる前に残しておく。
参考書を読んだり、ソースコードを読んでいると、コード内で呼び出されている既存メソッドが元々どこのクラス/モジュールに属しているのか知りたいときがある。そのメソッドの詳細を求めてライブラリドキュメントを読む目的であることが多い。
自クラスの先祖(スーパークラスおよびinclude済みのモジュール)は、以下のように求めることができる。
これで理屈上、全ての親クラス(スーパークラス)とinclude済みモジュールのメソッド名を把握できると思ったのだが、少し甘かった。
どういうことかというと。
クラスの場合はRubyは単一継承しか認めないためこの方法で問題はない。しかしモジュールの場合、モジュール中に別のモジュールがincludeされてしまうと、その別モジュールに関して上記方法では追跡できないという問題が起きてしまう。
この問題についてRuby-talk ML で質問したところ、知りたいメソッド名が分かっているならもっと簡単な方法があるとの教えを受けた。以下がそれである。
selfの継承するクラスもしくはモジュールのメソッド名を引数に、Objectクラスのインスタンスメソッドである'method'を呼び出すと、Methodクラスのインスタンスが手に入る。そのインスタンスメソッド'source_location'を使うとメソッドの定義してあるファイル名と、定義箇所の行数で構成した配列を入手できるのだ。これは便利! ありがとうDavis!
注:ruby で定義されていない(つまりネイティブ である)場合は nil であることに注意。
例えば method(:p).source_location とやっても、pはネイティブ(=Ruby本体に組み込まれている)のでソースファイルは存在しない。
参考書を読んだり、ソースコードを読んでいると、コード内で呼び出されている既存メソッドが元々どこのクラス/モジュールに属しているのか知りたいときがある。そのメソッドの詳細を求めてライブラリドキュメントを読む目的であることが多い。
自クラスの先祖(スーパークラスおよびinclude済みのモジュール)は、以下のように求めることができる。
#インクルード済モジュール名の配列を得る
modules = self.class.included_modules
#全スーパークラス及びinclude済モジュール名の配列を得る
ancestors = self.ancestors
#全祖先の集合からモジュール名の集合を引くとクラス名だけの集合になる
super_classes = ancestors - modules
eval( "#{super_classes}.class.public_instance_methods") #publicメソッド名配列取得
eval( "#{super_classes}.class.public_instance_methods") #protectedメソッド名配列取得
eval( "#{super_classes}.class.public_instance_methods") #privateメソッド名配列取得
これで理屈上、全ての親クラス(スーパークラス)とinclude済みモジュールのメソッド名を把握できると思ったのだが、少し甘かった。
どういうことかというと。
クラスの場合はRubyは単一継承しか認めないためこの方法で問題はない。しかしモジュールの場合、モジュール中に別のモジュールがincludeされてしまうと、その別モジュールに関して上記方法では追跡できないという問題が起きてしまう。
この問題についてRuby-talk ML で質問したところ、知りたいメソッド名が分かっているならもっと簡単な方法があるとの教えを受けた。以下がそれである。
source_file_name, line = *(method( :method_name).source_location)
selfの継承するクラスもしくはモジュールのメソッド名を引数に、Objectクラスのインスタンスメソッドである'method'を呼び出すと、Methodクラスのインスタンスが手に入る。そのインスタンスメソッド'source_location'を使うとメソッドの定義してあるファイル名と、定義箇所の行数で構成した配列を入手できるのだ。これは便利! ありがとうDavis!
注:ruby で定義されていない(つまりネイティブ である)場合は nil であることに注意。
例えば method(:p).source_location とやっても、pはネイティブ(=Ruby本体に組み込まれている)のでソースファイルは存在しない。
PR
カレンダー
フリーエリア
最新CM
最新記事
(06/05)
(06/04)
(06/04)
(11/18)
(11/18)
ブログ内検索
最古記事
(09/15)
(09/20)
(09/27)
(09/27)
(10/11)
COMMENT