28
class C1
  def pr
    puts 'C1'
  end
end

class C2 < C1
  def pr
    puts 'C2'
    super
    puts self.method(:pr).source_location
  end
end

c = C2.new
c.pr

上記のプログラムでは、メソッドを使用してコードの場所を取得するだけでなく、 super(C1::prこの場合)によって実行されたコードの場所を取得することは可能ですか?C2::prsource_location

4

5 に答える 5

31

super_methodRuby 2.2 からは、次のように使用できます。

Class A
  def pr
    puts "pr"
  end
end

Class B < A
  def pr
    puts "Super method: #{method(:pr).super_method}"
  end
end

メソッドを返すようsuper_methodに、それらをチェーンして祖先を見つけることができます。

def ancestor(m)
  m = method(m) if m.is_a? Symbol
  super_m = m.super_method
  if super_m.nil?
    return m
  else
    return ancestor super_m
  end
end
于 2015-06-06T15:27:46.523 に答える
9

スーパークラスにアクセスしてから、 を使用instance_methodしてスーパークラスからメソッドを取得するだけです。

class C2 < C1
  def pr
    puts "C2"
    super
    puts "Child: #{self.method(:pr).source_location}"
    puts "Parent: #{self.class.superclass.instance_method(:pr).source_location}"
  end
end

EDIT —祖先チェーンのチェックに関するコメントに関しては、(驚くべきことに)不要なようです。

class C1
  def pr
    puts "C1"
  end
end

class C2 < C1; end

class C3 < C2
  def pr
    puts "C3"
    super
    puts "Child source location: #{self.method(:pr).source_location}"
    puts "Parent source location: #{self.class.superclass.instance_method(:pr).source_location}"
  end
end

c = C3.new
c.pr

版画

C3
C1
Child source location: ["source_location.rb", 10]
Parent source location: ["source_location.rb", 2]
于 2013-04-29T16:52:59.387 に答える
5

pryを使用している場合は、-sフラグを使用してスーパー メソッドを表示できます。この機能に関するドキュメントはこちらです。

show-source Class#method -s
于 2015-02-24T11:49:05.223 に答える
1

メソッドの祖先全体を見るには...

irbセッションでこれを定義します。

class Object
  def method_ancestry(method_name)
    method_ancestors = []
    method = method(method_name)
    while method
      method_ancestors << [method.owner, method.source_location]
      method = method.super_method
    end
    method_ancestors
  end
end

たとえば、Rails コンソールでは、次のことができます。

# assuming User is an ActiveRecord class
User.new.method_ancestry(:save)

=> [[ActiveRecord::Suppressor,
  ["/Users/me/.gem/ruby/2.3.1/gems/activerecord-5.0.1/lib/active_record/suppressor.rb", 40]],
 [ActiveRecord::Transactions,
  ["/Users/me/.gem/ruby/2.3.1/gems/activerecord-5.0.1/lib/active_record/transactions.rb", 317]],
 [ActiveRecord::AttributeMethods::Dirty,
  ["/Users/me/.gem/ruby/2.3.1/gems/activerecord-5.0.1/lib/active_record/attribute_methods/dirty.rb",
   21]],
 [ActiveRecord::Validations,
  ["/Users/me/.gem/ruby/2.3.1/gems/activerecord-5.0.1/lib/active_record/validations.rb", 43]],
 [ActiveRecord::Persistence,
  ["/Users/me/.gem/ruby/2.3.1/gems/activerecord-5.0.1/lib/active_record/persistence.rb", 124]]]

superこのリストだけでは、リストされているメソッド定義のいずれかが実際に呼び出しているのか、継承された定義を単にオーバーライドしているのかはわかりません。しかしsuper、それらの 1 つに表示されている場合は、リストの次のものに移動します。

~/.irbrcこれを頻繁に使用する場合は、またはに入れることができます~/.pryrc

于 2017-02-13T14:33:21.430 に答える