user1868607
user1868607

Reputation: 2600

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?

Upvotes: 1

Views: 343

Answers (3)

Myst
Myst

Reputation: 19221

I believe it has to do with the difference of declaring the .protegido method as part of the meta-class (or singleton class) rather than as part of the B class itself.

Read about it here: Metaprogramming in Ruby: It's All About the Self

Upvotes: 0

pramod
pramod

Reputation: 2318

In case of Protected methods, we can call them from the scope of any object belonging to the same class. In your code snippet, as per the scope of the class, method lookup chain picks up that method as it is inherited to super class. It means, you are defining a method in its Singleton class means we can call it by using objects of that class. so we can call it by the object of A and B because of B object inherited from A.

In one word you can call a protected method in a public method of the class. Please refer the below urls for better understanding

http://nithinbekal.com/posts/ruby-protected-methods/

accessing protected methods in Ruby

Upvotes: 0

Aetherus
Aetherus

Reputation: 8888

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.

Upvotes: 1

Related Questions