2016-03-09 2 views
0

Предположим, у меня есть следующие:Какова область применения переменных и методов, включенных через модули 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 

Итак, у меня есть несколько основных вопросов.

  1. Что происходит за кулисами в отношении Var против var? Похоже, что заглавное имя переменной больше, чем просто соглашение.
  2. Когда include Модуль, какие вещи передаются классу включения и в какой области?
  3. Есть ли способ сделать обратное? То есть использование include включает в себя переменную экземпляра или метод класса?
+0

Часть ответа заключается в том, что для непосредственного доступа к методам модулей они должны быть, ну, методы модуля, а не методы экземпляра. Поэтому вам нужно определить 'def self.hello_world ...' для получения 'MyModule :: SubModule.hello_world =>« привет мир! »'. Кроме того, вы можете оставить метод hello_world методом экземпляра и добавить строку 'extend self' в конце' SubModule', чтобы сделать метод hello_world модулем (а также метод экземпляра). –

ответ

3

Что происходит за кулисами в отношении Var vs var? Похоже, что заглавное имя переменной больше, чем просто соглашение.

Да, конечно, это не конвенция. Переменные, начинающиеся с буквы верхнего регистра, являются константами, переменными, начинающимися с буквы нижнего регистра, являются локальные переменные. Они совершенно разные.

Когда include Модуль, какие вещи передаются классу включения и в какой области?

Ничто не проходит нигде. include Использование mixin просто делает это смешивание суперкласса класса, в котором вы находитесь include Ввод его в. Это все. Все остальное работает точно так же, как с классами.

Есть ли способ сделать обратное? То есть использование include включает в себя переменную экземпляра или метод класса?

Я не понимаю этот вопрос. Переменные экземпляра не имеют ничего общего с миксинами или классами. Они принадлежат экземплярам, ​​поэтому их называют «экземплярами» переменных.

В Ruby нет таких вещей, как «методы класса». Ruby знает только один метод: методы экземпляра. Когда рубисты разговаривают друг с другом, они иногда используют термин «метод класса» для обозначения «одиночного метода объекта, который является классом», но они делают это, полностью зная, что методы класса фактически не существуют, просто стенография в разговоре. (И, конечно, одномерных методов тоже не существует, они просто удобный способ сказать «метод экземпляра одноэлементного класса».)

Смежные вопросы