Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Ruby handle inheritance for nested classes?

In the following test case:

class Package
    class Component
        def initialize
            p [:initialize,self]
        end
    end
end

class Package_A < Package
end

class Package_B < Package
end

# Why are the following components of type Package and not Package_A and Package_B
component=Package_A::Component.new
p component

component=Package_B::Component.new
p component

Results in:

[:initialize, #<Package::Component_1:0x2c0a8f8>]
#<Package::Component:0x2c0a8f8>
[:initialize, #<Package::Component_1:0x2c0a5b0>]
#<Package::Component:0x2c0a

How do I get a specific Package_A.component and Package_B.component?

like image 200
DMisener Avatar asked Jul 19 '11 12:07

DMisener


People also ask

Can nested classes be inherited?

A static nested class can inherit: an ordinary class. a static nested class that is declared in an outer class or its ancestors.

How does inheritance work in Ruby?

Inheritance is when a class inherits behavior from another class. The class that is inheriting behavior is called the subclass and the class it inherits from is called the superclass. We use inheritance as a way to extract common behaviors from classes that share that behavior, and move it to a superclass.

Can a class inherit from multiple classes Ruby?

Ruby supports only single class inheritance, it does not support multiple class inheritance but it supports mixins. The mixins are designed to implement multiple inheritances in Ruby, but it only inherits the interface part.

Can a class inherit from a module Ruby?

The Ruby class Class inherits from Module and adds things like instantiation, properties, etc – all things you would normally think a class would have. Because Module is literally an ancestor of Class , this means Modules can be treated like classes in some ways. As mentioned, you can find Module in the array Class.


1 Answers

Class Component is declared in Package, so it seems correct. The :: tells to look up the name Component in the scope of Package_A. Since there is no Component there, it looks up the superclass.

This example shows how to achieve what you want. There might be a simpler way, I would be happy to see it.

class Package
  class Component
    def foo
      puts "bar"
    end
  end
end

class Pack_a < Package
end

Pack_a::Component.new.foo
#=> bar
# as expected, though we actually have Package::Component

class Pack_b < Package
  class Component
  end
end

Pack_b::Component.new.foo
#=> NoMethodError: undefined method 'foo' for Pack_b::Component
# this error is because Pack_b::Component has nothing to do with Package::Component

class Pack_c < Package
  class Component < Package::Component
  end
end

Pack_c::Component.new.foo
#=> bar
# as expected

Pack_c::Component.new
#=> Pack_c::Component
# this Component is a subclass of Package::Component

This more-less should explain how scope works in such cases. Hope this helps.

like image 160
Miki Avatar answered Sep 28 '22 00:09

Miki