Ruby での利用可能なメソッドの確認

Written by @dr_taka_n at 2009/05/17 23:24 []

リフレクションを使用して確認をするのが手っ取り早い。 使い方が微妙なときは、ri で確認する。 本や Web で確認するまでもなく、大概のものはこのツープラトンで片付いたりする。

確認方法をメモしておく。

リフレクションによる確認

$ irb --prompt simple
>> class A
>>   def an_instance_method; end
>> 
?>   def self.a_class_method; end
>> end
=> nil
>> a1 = A.new
=> #<A:0x10c76b8>
>> a2 = A.new
=> #<A:0x10c5b24>
>> class << a1
>>   def a_singleton_method; end
>> end
=> nil

A クラスを定義し、インタスタンスメソッドとクラス(singleton)メソッドを定義しておく。 A クラスのインスタンスを a1a2 と2つ用意する。 a1 のインスタンスには a1 の特異メソッドを定義しておく。

クラスに対するメソッドの確認と、インスタンスに対するメソッドの確認を行う。 まずは、クラスに対して。

>> A.instance_methods(false)
=> ["an_instance_method"]
>> A.singleton_methods(false)
=> ["a_class_method"]

Module#instance_methods は、レシーバーのパブリックなメソッドを返す。 しかし、特異メソッドは含まない。引数を1つ取るが、デフォルト引数の値は true となっており、この場合、super クラスのメソッドも含めて出力される。そのクラスのメソッドだけを見たい場合には、false を指定する。

Object#singleton_methods は、レシーバの特異メソッドを返す。こちらも引数を1つ取るが、デフォルト引数の値は true となっており、この場合、include されたモジュールのメソッドも含む。そのクラスのメソッドだけを見たい場合には、false を指定する。

次にインスタンスに対して。

>> a1.methods - Object.methods
=> ["an_instance_method", "a_singleton_method"]

Object のメソッドはここでは表示から外すようにしている。 インスタンスメソッド、特異メソッド両方のメソッドを確認できる。

特異メソッドのみ表示したい場合には、

>> a1.methods(false)
=> ["a_singleton_method"]

引数に false を指定する。

>> a2.methods - Object.methods
=> ["an_instance_method"]
>> a2.methods(false)
=> []

a2 に対しては、特異メソッドは定義していないので表示されない。

メソッド名の見当がだいたい付いているような場合には、Enumerable#grep で結果のフィルタリングをする。

>> Array.instance_methods.grep(/each/)
=> ["each_index", "reverse_each", "each_with_index", "each"]

ri(fri) による確認

普通に Ruby をインストールしていれば、コマンドラインからリファレンスマニュアルの検索、表示が可能な ri コマンドも入っているので、すぐに利用可能となっている。

ただ・・・この ri コマンドは遅い。。ので、fri を使用している。

fast-riserver サーバを事前に起動しておく必要があるが、頻繁に ri を使う場合などは、そのスピードの違いからも入れておいた方がよい。 (ローカルモードでも使えるようになっているようだが、サーバを起動して使用するモード(remote mode)の方が若干速いようだ)

コマンドは、ri に fast の f のついた fri になる。

$ fri method_missing
------------------------------------------------------ Multiple choices:

     ActionController::Integration::Runner#method_missing, 
     ActionController::RewindableInput::RewindableIO#method_missing, 
     ActionController::TestProcess#method_missing, 
     ActiveRecord::Migration.method_missing, 
     ActiveSupport::Multibyte::Chars#method_missing, 
     ActiveSupport::StringInquirer#method_missing, 
     ActiveSupport::TimeWithZone#method_missing, 
     Builder::CSS#method_missing, Builder::XmlBase#method_missing, 
     CodeRay::Tokens#method_missing, 
     Cucumber::Broadcaster#method_missing, 
     DRb::DRbObject#method_missing, Delegator#method_missing, 
     Gem::FileOperations#method_missing, Gem::SilentUI#method_missing, 
     Kernel#method_missing, Nokogiri::Decorators::Slop#method_missing, 
     Nokogiri::XML::Builder#method_missing, 
     REXML::Functions.method_missing, REXML::QuickPath.method_missing, 
     Rack::Auth::Digest::Request#method_missing, 
     Rake::TaskArguments#method_missing, 
     SOAP::SOAPReference#method_missing, TempIO#method_missing
$ fri Kernel#method_missing
-------------------------------------------------- Kernel#method_missing
     obj.method_missing(symbol [, *args] )   => result
------------------------------------------------------------------------
     Invoked by Ruby when obj is sent a message it cannot handle. 
     symbol is the symbol for the method called, and args are any 
     arguments that were passed to it. By default, the interpreter 
     raises an error when this method is called. However, it is 
     possible to override the method to provide more dynamic behavior. 
     The example below creates a class Roman, which responds to methods 
     with names consisting of roman numerals, returning the 
     corresponding integer values.

        class Roman
          def romanToInt(str)
            # ...
          end
          def method_missing(methId)
            str = methId.id2name
            romanToInt(str)
          end
        end
     
        r = Roman.new
        r.iv      #=> 4
        r.xxiii   #=> 23
        r.mm      #=> 2000

RubyGems で新しい Gem を追加した場合などは、

$ fastri-server -b

で、インデックスを再構築しておく。

blog comments powered by Disqus