Search code examples
rubyscopeclass-methodinstance-method

Calling inherited class method from instance method in Ruby


I've got the following Ruby code:

class B
  class << self
    protected
    def prot
      puts "victory"
    end
  end
end
class C < B
  def self.met
    C.prot
  end
end

C.met

which tries to proof that protected class methods are inherited in Ruby. The problem is that if I convert met method to an instance method like this:

class B
  class << self
    protected
    def prot
      puts "victory"
    end
  end
end
class C < B
  def met
    C.prot
  end
end

c = C.new
c.met

it won't work. Maybe it has to do with class and instance methods scope?


Solution

  • It won't work, because the instance of C is not kind_of?(B.singleton_class).

    In ruby, a protected method can be called within the context of an object which is kind_of? the class which defines the method, with an explicit receiver which is also kind_of? the class which defines the method.

    You defined a protected method on the singleton class of B, so that method can only be called within the objects which are kind_of?(B.singleton_class). The class C inherits B, so C's singleton class inherits B's singleton class, so C is kind_of? B.singleton_class. Thus in your first case, it works. But obviously, C.new is not kind_of? B.singleton_class, so it won't work.