рубин супер ключевое слово - PullRequest
57 голосов
/ 08 апреля 2010

Насколько я понимаю, ключевое слово 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

Этот код взят из главной ветки рельсов. Большое спасибо.

Ответы [ 6 ]

45 голосов
/ 09 апреля 2010

Пример, приведенный в Документах Ruby для ключевого слова 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!

15 голосов
/ 08 апреля 2010

Отметьте objRef.class.ancestors или ClassName.ancestors, чтобы узнать цепочку наследования. Если суперкласс не содержит метод, то проверяются все модули, включенные в суперкласс (последний включается первым). Если совпадения нет, то он поднимается на один уровень вверх к классу прародителя и т. Д.
Вы можете использовать список предков, а затем вызвать AncestorClass.methods.select{|m| m.include?("auto_load")} для определения зоны вызываемого метода.

(Примечание: вышеприведенный код Ruby 1.8. В 1.9 methods возвращает символы вместо строк. Поэтому вам нужно будет сделать m.to_s.include?(...)

14 голосов
/ 28 июня 2012

Использование Прай

Вставьте вызов 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>    
5 голосов
/ 08 апреля 2010

Ключевое слово super проверяет весь путь до дерева предков, чтобы найти унаследованный метод.

Выполнить поиск по всей основной ветке рельсов. В active_support/lib/active_support/dependencies/autoload.rb.

вы найдете только один def autoload, который вам нужен.

Переопределенный метод является родным Ruby. Это Module#autoload

2 голосов
/ 20 июня 2011

Я добавил этот метод, чтобы найти владельца метода в моем .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
1 голос
/ 08 апреля 2010

Соответствующий метод суперкласса, вероятно, Модуль # автозагрузка .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...