私が理解していることから、super
キーワードは、現在のクラスのスーパークラスの現在のメソッドと同じ名前のメソッドを呼び出します。以下のautoload
メソッドには、super
の呼び出しがあります。どのスーパークラスで同じ名前のメソッドが見つかるか、またはsuper
の呼び出しがここで何をするのかを知りたい
module ActiveSupport
module Autoload
...
def autoload(const_name, path = @@at_path)
full = [self.name, @@under_path, const_name.to_s, path].compact.join("::")
location = path || Inflector.underscore(full)
if @@eager_autoload
@@autoloads[const_name] = location
end
super const_name, location
end
....
end
end
module ActiveRecord
extend ActiveSupport::Autoload
...
autoload :TestCase
autoload :TestFixtures, 'active_record/fixtures'
end
このコードはRails masterブランチからのものです。ありがとうございました。
super
キーワードのドキュメント で提供されている例:module Vehicular
def move_forward(n)
@position += n
end
end
class Vehicle
include Vehicular # Adds Vehicular to the lookup path
end
class Car < Vehicle
def move_forward(n)
puts "Vrooom!"
super # Calls Vehicular#move_forward
end
end
puts Car.ancestors.inspect
# Output
# [Car, Vehicle, Vehicular, Object, Kernel, BasicObject]
Vehicular
Module
オブジェクトが含まれていることに注意してください!
_objRef.class.ancestors
_または_ClassName.ancestors
_をチェックして、継承チェーンを確認します。スーパークラスにメソッドが含まれていない場合、スーパークラスに含まれるすべてのモジュールがチェックされます(最後に含まれるモジュールが最初にチェックされます)。一致しない場合、1つ上のレベルの祖父母クラスに移動します。
先祖のリストを使用してから、AncestorClass.methods.select{|m| m.include?("auto_load")}
を呼び出して、呼び出されているメソッドをゾーニングできます。
(注:上記のコードはRuby 1.8です。1.9ではmethods
は文字列ではなくシンボルを返します。したがって、_m.to_s.include?(...
_を実行する必要があります)
Pry を使用します
super
を使用する直前にbinding.pry
呼び出しを挿入し、show-source -s
(-s
はsuperclass
を意味します)を呼び出して、スーパークラスメソッドを表示し、定義されている場所を見つけます。 :
class A
def hello
puts "hi"
end
end
class B < A
def hello
binding.pry
super
end
end
b = B.new
b.hello
From: (pry) @ line 7 B#hello:
7: def hello
=> 8: binding.pry
9: super
10: end
[1] (pry) #<B>: 0> show-source -s
From: (pry) @ line 2:
Number of lines: 3
Owner: A # <--see owner here (i.e superclass)
Visibility: public
def hello
puts "hi"
end
[2] (pry) #<B>: 0>
super
キーワードは、継承されたメソッドを見つけるために、祖先ツリーをずっと調べます。
Rails masterブランチ全体で検索を実行します。def autoload
で見ているものとまったく同じactive_support/lib/active_support/dependencies/autoload.rb
]のみが見つかります。
オーバーライドされるメソッドはネイティブRubyです。 Module#autoload
メソッドの所有者を見つけるためにこのメソッドを.irbrcに追加しましたが、特にシングルトンクラスのスーパークラスがスーパークラスのシングルトンクラスであるシングルトンメソッドを処理する場合、これを行うより良い方法がありますか?
class Object
def find_method(method_string)
if klasses = self.class.ancestors.select { |a| a if a.methods.include? method_string }
puts "class method in #{klasses.join(',')}" unless klasses.empty?
end
if klasses = self.class.ancestors.select { |a| a if a.instance_methods.include? method_string }
puts "instance method in #{klasses.join(',')}" unless klasses.empty?
end
rescue
raise "owning class not found"
end
end
関連するスーパークラスメソッドは、おそらく Module#autoload です。