ruby super keyword

Ruby on-RailsRubyActiverecord

Ruby on-Rails Problem Overview


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 autoload method, 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 super do here

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.

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

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!

Solution 2 - Ruby on-Rails

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?(...)

Solution 3 - Ruby on-Rails

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>    

Solution 4 - Ruby on-Rails

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

Solution 5 - Ruby on-Rails

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

Solution 6 - Ruby on-Rails

The relevant superclass method is probably Module#autoload.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser290870View Question on Stackoverflow
Solution 1 - Ruby on-RailsmačekView Answer on Stackoverflow
Solution 2 - Ruby on-RailsGishuView Answer on Stackoverflow
Solution 3 - Ruby on-RailshorseyguyView Answer on Stackoverflow
Solution 4 - Ruby on-RailsmačekView Answer on Stackoverflow
Solution 5 - Ruby on-RailsEric SteenView Answer on Stackoverflow
Solution 6 - Ruby on-RailsGreg CampbellView Answer on Stackoverflow