Ключевое слово 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

Пример, представленный в Ruby Docs для 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!

Ответ 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.