据我所知,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分支。非常感谢。
答案 0 :(得分:45)
super
keyword: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
对象!
答案 1 :(得分:15)
检查objRef.class.ancestors
或ClassName.ancestors
以了解继承链。如果超类不包含该方法,则检查超类包含的所有模块(最后包括先检查)。如果没有匹配,则它向上移动一级到祖父母班级,依此类推
您可以使用祖先列表,然后调用AncestorClass.methods.select{|m| m.include?("auto_load")}
来区分正在调用的方法。
(注意:上面的代码是Ruby 1.8。在1.9 methods
中返回符号而不是字符串。所以你必须做m.to_s.include?(...
)
答案 2 :(得分:14)
使用Pry
在使用binding.pry
之前插入super
来电,然后调用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>
答案 3 :(得分:5)
super
关键字检查祖先树的所有方向以查找继承的方法。
在整个rails master分支上搜索。您只会找到一个def autoload
,这正是您在active_support/lib/active_support/dependencies/autoload.rb
中看到的那个。{/ p>
被覆盖的方法是原生Ruby。它是Module#autoload
答案 4 :(得分:2)
我添加了这个方法来查找我的.irbrc方法的所有者,有没有人看到更好的方法来做到这一点,特别是在处理单例类的超类是超类的单例类的单例方法? / p>
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
答案 5 :(得分:1)
相关的超类方法可能是Module#autoload。