Сначала вам нужно понять, что Ruby ищет константы, несколько похожие на методы. Он начинается с поиска константы в текущем лексическом диапазоне . Если он не найдет константу, она поднимается на один уровень и смотрит туда и т. Д. Если он не может найти постоянную нигде, он в конечном итоге ищет верхний уровень, поэтому вы можете получать доступ к модулям, например Kernel
, из любого места вашего кода.
module Star
end
Star.object_id # 20
module Dollar
Star.object_id # 20. No Star in current scope, so gets the top-level star
end
module At
module Star
end
Star.object_id # 10. There is now a Star in this scope, so we don't get the top-level one
end
Следующая вещь, чтобы понять, что методы, определенные на верхнем уровне в Ruby, сделаны экземпляр методы Object
. Поскольку все в Ruby является экземпляром Object
, такие методы всегда можно вызвать.
Наконец, рассмотрим, что делает include
: он принимает методы экземпляра из модуля и делает их экземплярами методов в текущей области. Так что если вы include
что-то на верхнем уровне, все эти методы добавляются в Object
!
Таким образом, ваш код, по существу, эквивалентно следующему:
module Star
def self.line
puts '*' * 20
end
# this overwrites the previous definition
def self.line
puts '$' * 20
end
end
# because of the way constants are looked up, the def ends up in Star
module Dollar
end
module At
def line
puts '@' * 20
end
end
# the include does this, so now every object (including Dollar) can call line
def line
puts '@' * 20
end
# except Star already has its own line method, so the one from Object won't be called for it
Star.line # "$$$$$$$$$$$$$$$$$$$$"
Почти. Ваши объяснения верны: 'include' на верхнем уровне включает в себя' Object', а с 'Dollar.is_a? (Object)' вы можете вызывать любой метод, который определен в 'Object' или смешанный в' Object', включая 'At # line'. Однако 'line' в' At' - это метод экземпляра ('At # line'), а не функция модуля (' At :: line'), и именно поэтому это работает. –
@ JörgWMittag Спасибо!Ваше понимание объектов Module/include/Object является способом глубже, чем у меня) –