Ruby on rails ruby超级关键字
据我所知,super关键字在当前类的超类中调用与当前方法同名的方法。在下面的自动加载方法中,有一个对super的调用。我想知道我会在哪个超类中找到一个同名的方法,或者调用super在这里做什么Ruby on rails ruby超级关键字,ruby-on-rails,ruby,activerecord,Ruby On Rails,Ruby,Activerecord,据我所知,super关键字在当前类的超类中调用与当前方法同名的方法。在下面的自动加载方法中,有一个对super的调用。我想知道我会在哪个超类中找到一个同名的方法,或者调用super在这里做什么 此代码来自rails主分支。非常感谢。相关的超类方法可能是。检查objRef.class.祖先或ClassName.祖先以了解继承链。如果该超类不包含该方法,则首先检查该超类包含的所有模块。如果没有匹配,那么它将向上移动一个级别到祖父母类,以此类推。 您可以使用祖先列表,然后调用AncestorClass
此代码来自rails主分支。非常感谢。相关的超类方法可能是。检查objRef.class.祖先或ClassName.祖先以了解继承链。如果该超类不包含该方法,则首先检查该超类包含的所有模块。如果没有匹配,那么它将向上移动一个级别到祖父母类,以此类推。 您可以使用祖先列表,然后调用AncestorClass.methods。选择{| m | m.include?auto|u load}以进入正在调用的方法 注意:上面的代码是Ruby 1.8。在1.9中,方法返回符号而不是字符串。因此,您必须执行一个m.to_.include?..关键字检查祖先树的所有路径,以找到继承的方法 在整个rails主分支上执行搜索。您只能在active_support/lib/active_support/dependencies/autoload.rb中找到一个def autoload,它正是您正在查看的def autoload 被重写的方法是原生Ruby。这是Ruby文档中为以下内容提供的示例:
请注意,包含车辆模块对象 我添加此方法是为了找到my.irbrc中某个方法的所有者,是否有人认为有更好的方法可以做到这一点,特别是在处理singleton类的超类是超类的singleton类的singleton方法时
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
使用
在使用super之前插入binding.pry调用,然后调用show source-s-s means 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>
模块是如何成为ActiveSupport::Autoload的超类的?它将是ActiveSupport::Autoload的类,对吗?谢谢。@ash34,super一直在祖先树上查找,直到找到最接近的继承方法。有关更多详细信息,请参阅我的答案。您能解释一下模块是如何成为祖先树的一部分的吗。任何包含“ActiveSupport::Autoload”的类都会将方法“Autoload”作为实例方法。根据我的理解,除了类“class”之外的任何类的超类都是Object。因此,当类“C”的一个实例调用“autoload”时,super应该查看作为Object的超类“C”。我缺少什么。@ash34,这些都包装在模块ActiveSupport中,它是一个模块对象。@ash34,包含的模块是类祖先的一部分。检查示例Array.祖先以查看其检查方法定义的模块和类的列表。您好,根据您的示例,“模块”不在祖先树中,您所指的自动加载方法在Moduleautoload中。我要说的是ActiveSupport.class是模块,但它不是超类。ActiveSupport.superclass会给你一个错误Hi参数呢?如果你只是从汽车中调用super,它会自动传递到车辆的super吗?@deepak对pry的find方法hello的建议更为方便!也许我并没有按照你的意图阅读你的答案,但是我理解在祖先链中检查的第一个位置不是超类,而是当前类中包含的模块。只有在这些都用完之后,搜索才会转到超级类。我发现这有助于理解发生了什么。
puts Car.ancestors.inspect
# Output
# [Car, Vehicle, Vehicular, Object, Kernel, BasicObject]
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
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>