rubyruby-2.2

Why base class method is being called inside inherited?


In self.inherited method of base class, subclass is passed, calling subclass's name method instead calls base class method. Though same thing works If same method is called on same class elsewhere

class A
 def self.name 
  "a"
 end

 def self.inherited(subclass)
  puts B.hash
  puts B.name
 end
end

class B < A
 def self.name 
  "b"
 end
end

puts B.hash
puts B.name

output:

1428955046062147697
a
1428955046062147697
b

Solution

  • No magic here.

    When you declare B the things happen in the following order (roughly speaking):

    1. B (an instance of Class) is created (which inherits everything from A). At this moment it doesn't have anything specific.

    2. A.inherited hook is invoked.

    3. B class is opened and processed. Only at this point, it gets its own properties and methods (except the ones that could be created inside the hook).

    So, when (2) happens the only name that is available for B is the one defined in A.

    This is very easy to check using the following code:

    class A
      def self.name 
        "a"
      end
    
      def self.inherited(subclass)
        puts "B own methods, point 1: #{subclass.methods(false).join(', ')}"
      end
    end
    
    class B < A
      puts "B own methods, point 2: #{self.methods(false).join(', ')}"
    
      def self.name 
        "b"
      end
    
      puts "B own methods, point 3: #{self.methods(false).join(', ')}"
    end
    
    # B own methods, point 1: 
    # B own methods, point 2: 
    # B own methods, point 3: name
    

    Everything is clear now, right?