简体   繁体   中英

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM