Каков объем переменных и методов, включенных в модули 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. Когда includeing модуль, какие вещи передаются включенному классу и в какой области?
  3. Есть ли способ сделать наоборот? То есть использовать include для включения переменной экземпляра или метода класса?

person Teofrostus    schedule 09.03.2016    source источник
comment
Часть ответа заключается в том, что для прямого доступа к методам модуля они должны быть методами модуля, а не методами экземпляра. Итак, вам нужно определить def self.hello_world..., чтобы получить MyModule::SubModule.hello_world => "hello world!". Кроме того, вы можете оставить hello_world методом экземпляра и добавить строку extend self в конце SubModule, чтобы сделать hello_world методом модуля (а также методом экземпляра).   -  person Cary Swoveland    schedule 10.03.2016


Ответы (1)


Что происходит за кулисами в отношении Вар против Вар? Похоже, что использование заглавных букв в имени переменной — это больше, чем просто соглашение.

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

При includeing модуле какие вещи передаются включающему классу и в какой области?

Ничего никуда не передается. includeДобавление миксина просто делает этот миксин надклассом класса, в который вы includeдобавляете его. Это все. Все остальное тогда работает точно так же, как с классами.

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

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

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

person Jörg W Mittag    schedule 09.03.2016