Классы Ruby в классах (или модулях в модулях)
Поскольку я читаю разные книги Ruby, я заметил, что классы Ruby могут быть определены в других классах или модулях Ruby. Вот пример класса внутри класса:
class Outerclass
def foobar
puts "FOOBAR"
end
class Innerclass
def barfoo
puts "BARFOO"
end
end
end
Вот код, который я запускал в IRB, чтобы понять это концептуально:
oc = Outerclass.new # => #<Outerclass:0x00000100a46478>
Outerclass.instance_methods(false) # => [:foobar]
ic = Outerclass::Innerclass.new # => #<Outerclass::Innerclass:0x00000100a0b120>
ic = Outerclass::Innerclass.instance_methods(false) # => [:barfoo]
Вот мои вопросы:
-
Когда интерпретатор ruby впервые встречает мой код определения класса выше, он просматривает методы, которые я написал, и где-нибудь их где-то храню? Я знаю, что метод экземпляра "foobar" фактически не запускается, поскольку в определении Outerclass нет вызова.
-
Устранив первый вопрос, как насчет того, когда Ruby сталкивается с классом Innerclass? Что здесь происходит?
-
В общем, каковы некоторые причины, по которым вы хотели бы иметь классы внутри классов? Есть ли какие-либо преимущества для этого?
-
Означает ли экземпляр Outerclass что-либо о классе Innerclass?
-
Означает ли экземпляр Innerclass что-либо о классе Outerclass?
Оцените любую помощь, которую вы можете предоставить!
Ответы
Ответ 1
Когда интерпретатор просматривает этот файл, он назначает классы следующим образом:
OuterClass = Class.new do
def foobar
puts "FOOBAR"
end
InnerClass = Class.new do
def barfoo
puts "BARFOO"
end
end
end
Итак, когда Ruby встречает вложенный класс, он присваивает ему константу InnerClass
, которой присваивается константа OuterClass
. Они не имеют никакого отношения друг к другу.
InnerClass
не имеет наследования OuterClass
:
InnerClass.ancestors
=> [InnerClass, Object, Kernel, BasicObject]
Когда вы вызываете константу OuterClass::InnerClass
, вы ссылаетесь на константу InnerClass
, которая именуется под константой OuterClass
, которая равна назначению ей инструкции Class.new.
Хорошая книга, чтобы прочитать об этом - "Метапрограммирование Рубина". Он посвящен деталям классов, синглтонов, модулей и т.д.