views:

258

answers:

4
+1  Q: 

ruby super keyword

Hi,

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.

A: 

The relevant superclass method is probably Module#autoload.

Greg Campbell
How is module the superclass of ActiveSupport::AutoloadIt would be the class of ActiveSupport::Autoload right?Thanks.
@ash34, `super` keeps going up the ancestry tree until it finds the the closest inherited method. See my answer for more details.
macek
+3  A: 

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

Gishu
+2  A: 

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

macek
Can you explain me how Module is part of the ancestry tree. Any class (let's say C) that includes 'ActiveSupport::Autoload' gets the method 'autoload' as an instance method. Per my understanding, the superclass of any class other than the class 'Class' is Object. So when an instance of our class 'C' calls 'autoload', the super should look in the superclass of 'C' which is Object. What am I missing.
@ash34, this is all wrapped inside `module ActiveSupport` which is a `Module` object.
macek
@ash34, included Modules are part of the ancestry of a class. Check for example `Array.ancestors` to see the list of modules and classes it checks for method definitions.
mckeed
A: 

I linked to this in my other answer but something tells me you didn't look at it.

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!

macek
Hi,Per your example 'Module' is not in the ancestry tree here and the autoload method you are referring to is in Module#autoload. What I am saying is ActiveSupport.class is Module but it is not the superclass.ActiveSupport.superclass will give you an error