ruby超级关键字

时间:2010-04-08 04:49:46

标签: ruby-on-rails ruby activerecord

据我所知,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

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

6 个答案:

答案 0 :(得分:45)

Ruby文档中为super keyword

提供的示例
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对象!

答案 1 :(得分:15)

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

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

答案 2 :(得分:14)

使用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>    

答案 3 :(得分:5)

super关键字检查祖先树的所有方向以查找继承的方法。

在整个rails master分支上搜索。您只会找到一个def autoload,这正是您在active_support/lib/active_support/dependencies/autoload.rb中看到的那个。{/ p>

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

答案 4 :(得分:2)

我添加了这个方法来查找我的.irbrc方法的所有者,有没有人看到更好的方法来做到这一点,特别是在处理单例类的超类是超类的单例类的单例方法? / p>

  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

答案 5 :(得分:1)

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