ruby 超级关键字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2597643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:30:44  来源:igfitidea点击:

ruby super keyword

ruby-on-railsrubyactiverecord

提问by user290870

From what I understand, superkeyword invokes a method with the same name as the current method in the superclass of the current class. Below in the autoloadmethod, there is a call to super. I would like to know in which superclass I would find a method with the same name or what does the call to superdo here

据我了解,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

This code is from the rails master branch. Thanks much.

此代码来自 rails master 分支。非常感谢。

回答by ma?ek

The example provided in the Ruby Docs for the superkeyword:

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

Inspecting ancestors

检查祖先

puts Car.ancestors.inspect

# Output
# [Car, Vehicle, Vehicular, Object, Kernel, BasicObject]

Note the inclusion of the VehicularModuleobject!

注意包含VehicularModule对象!

回答by Gishu

Check objRef.class.ancestorsor ClassName.ancestorsto know the inheritance chain. If the super class does not contain the method, then all modules included by the super class are checked (last included checked first). If no match, then it moves up one level to the grandparent class and so on.
You can use the list of ancestors and then call AncestorClass.methods.select{|m| m.include?("auto_load")}to zone in on the method that's being called.

检查objRef.class.ancestorsClassName.ancestors了解继承链。如果超类不包含该方法,则检查超类包含的所有模块(首先检查最后包含的模块)。如果不匹配,则它向上移动一级到祖父类,依此类推。
您可以使用祖先列表,然后AncestorClass.methods.select{|m| m.include?("auto_load")}在正在调用的方法上调用zone in。

(Note: the above code is Ruby 1.8. In 1.9 methodsreturns symbols instead of strings. so you'd have to do a m.to_s.include?(...)

(注意:上面的代码是 Ruby 1.8。在 1.9 中methods返回符号而不是字符串。所以你必须做一个m.to_s.include?(...

回答by horseyguy

Use Pry

使用

Insert a binding.prycall right before you use super, and then invoke show-source -s(-smeans superclass) to show the superclass method and find out where it's defined:

binding.pry在使用之前插入一个调用super,然后调用show-source -s( -smeans 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>    

回答by ma?ek

The superkeyword checks all the way up the ancestry tree to find the inherited method.

super关键字检查一路祖先树找到继承的方法。

Do a search on the entire rails master branch. You will only find one def autoloadwhich is exactly the one you're looking at in active_support/lib/active_support/dependencies/autoload.rb.

在整个 rails master 分支上进行搜索。您只会找到一个def autoload正是您正在查看的active_support/lib/active_support/dependencies/autoload.rb

The method being overridden is native Ruby. It is Module#autoload

被覆盖的方法是原生 Ruby。这是Module#autoload

回答by Eric Steen

I added this method to find the owner of a method to my .irbrc, does anyone see a better way to do this, especially in handling singleton methods where the superclass of the singleton class is the singleton class of the superclass?

我添加了这个方法来查找我的 .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

回答by Greg Campbell

The relevant superclass method is probably Module#autoload.

相关的超类方法可能是Module#autoload