ruby super keyword

后端 未结 6 1260
天命终不由人
天命终不由人 2020-12-12 20:45

From what I understand, super keyword invokes a method with the same name as the current method in the superclass of the current class. Below in the autol

相关标签:
6条回答
  • 2020-12-12 20:49

    The relevant superclass method is probably Module#autoload.

    0 讨论(0)
  • 2020-12-12 20:56

    Use Pry

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

    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>    
    
    0 讨论(0)
  • 2020-12-12 21:03

    Check objRef.class.ancestors or ClassName.ancestors to 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.

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

    0 讨论(0)
  • 2020-12-12 21:07

    The example provided in the Ruby Docs for the 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
    

    Inspecting ancestors

    puts Car.ancestors.inspect
    
    # Output
    # [Car, Vehicle, Vehicular, Object, Kernel, BasicObject]
    

    Note the inclusion of the Vehicular Module object!

    0 讨论(0)
  • 2020-12-12 21:07

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

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

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

    0 讨论(0)
  • 2020-12-12 21:16

    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?

      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
    
    0 讨论(0)
提交回复
热议问题