Ключевое слово ruby super
Из того, что я понимаю, ключевое слово 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
Этот код находится из ветки ведущего рельса. Большое спасибо.
Ответы
Ответ 1
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
!
Ответ 2
Проверьте objRef.class.ancestors
или ClassName.ancestors
, чтобы узнать цепочку наследования. Если суперкласс не содержит метода, то все модули, включенные суперклассом, проверяются (последний включенный проверяется первым). Если нет совпадения, то он поднимается на один уровень до класса дедушки и бабушки и т.д.
Вы можете использовать список предков, а затем вызвать AncestorClass.methods.select{|m| m.include?("auto_load")}
в зону внутри метода, который вызывается.
(Примечание: приведенный выше код - Ruby 1.8. В 1.9 methods
возвращает символы вместо строк, поэтому вам нужно сделать m.to_s.include?(...
)
Ответ 3
Используйте 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>
Ответ 4
super
ключевое слово проверяет все дерево родословной, чтобы найти унаследованный метод.
Сделайте поиск по всей ветке master rails. Вы найдете только один def autoload
, который вы точно найдете в active_support/lib/active_support/dependencies/autoload.rb
.
Переопределяемый метод - это собственный Ruby. Это Module#autoload
Ответ 5
Я добавил этот метод, чтобы найти владельца метода для моего .irbrc, может ли кто-нибудь увидеть лучший способ сделать это, особенно при обработке одноэлементных методов, где суперкласс класса 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
Ответ 6
Соответствующий метод суперкласса, вероятно, Module # autoload.