忍者ブログ

ぢみへんプログラミング日誌

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

Rubyでメソッドの定義してあるファイルを知る方法

Ruby-talk ML で便利な技を教えてもらったので忘れる前に残しておく。

参考書を読んだり、ソースコードを読んでいると、コード内で呼び出されている既存メソッドが元々どこのクラス/モジュールに属しているのか知りたいときがある。そのメソッドの詳細を求めてライブラリドキュメントを読む目的であることが多い。

自クラスの先祖(スーパークラスおよび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

COMMENT

NAME
TITLE
MAIL (非公開)
URL
EMOJI
Vodafone絵文字 i-mode絵文字 Ezweb絵文字
COMMENT
PASS (コメント編集に必須です)
SECRET
管理人のみ閲覧できます
 
  

カレンダー

04 2024/05 06
S M T W T F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

フリーエリア

最新CM

バーコード

ブログ内検索

Copyright ©  -- ぢみへんプログラミング日誌 --  All Rights Reserved

Design by CriCri / Material by petit sozai emi / powered by NINJA TOOLS / 忍者ブログ / [PR]