Предположим, у меня есть следующие:Какова область применения переменных и методов, включенных через модули ruby?
module MyModule
module SubModule
Var = 'this is a constant'
var = 'this is not a constant'
def hello_world
return 'hello world!'
end
end
end
В том же файле, я могу только показаться, чтобы получить доступ MyModule::SubModule::Var
, но не любая константа или метод. Если я теперь создать класс и включить эти модули по-разному, я получаю дополнительное странное поведение:
class MyClass
include MyModule
def initialize()
puts SubModule::Var
end
def self.cool_method
puts SubModule::Var
end
end
В этом случае, я могу снова доступ только Var
, но не другие два. SubModule::var
и SubModule::hello_world
не работает. Наконец:
class MyClass
include MyModule::SubModule
def initialize()
puts Var
puts hello_world
end
def self.cool_method
puts Var
puts hello_world
end
end
В этом случае, я могу теперь получить доступ как Var
и метод hello_world
но не var
, и, самое странное, что hello_world
по-видимому, стал метод экземпляра! То есть, звонок hello_world
в initialize
работает, но тот, который находится в self.cool_method
, нет. Это довольно странно, учитывая, что Var
, кажется, был включен в качестве переменной класса, так как за пределами класса, я должен получить доступ к ним так:
MyClass::Var
x = MyClass.new
x.hello_world
Итак, у меня есть несколько основных вопросов.
- Что происходит за кулисами в отношении
Var
противvar
? Похоже, что заглавное имя переменной больше, чем просто соглашение. - Когда
include
Модуль, какие вещи передаются классу включения и в какой области? - Есть ли способ сделать обратное? То есть использование include включает в себя переменную экземпляра или метод класса?
Часть ответа заключается в том, что для непосредственного доступа к методам модулей они должны быть, ну, методы модуля, а не методы экземпляра. Поэтому вам нужно определить 'def self.hello_world ...' для получения 'MyModule :: SubModule.hello_world =>« привет мир! »'. Кроме того, вы можете оставить метод hello_world методом экземпляра и добавить строку 'extend self' в конце' SubModule', чтобы сделать метод hello_world модулем (а также метод экземпляра). –