Считается ли использование Module # module_function неправильным? - PullRequest
1 голос
/ 13 февраля 2012

Похоже, если вы хотите иметь возможность вызывать методы в модуле (/ Class), вы ищете одиночный код ... И если это так, вам лучше использовать методы класса или Singleton mixin (не ищите ответов, какой из них "лучше").

Единственное преимущество (?), Которое я вижу при использовании #module_function, - это гибкость, которую можно смешивать в модуле, а также вызывать методы модуля. Есть что-нибудь еще?

Я наткнулся на какой-то старый код, который раньше работал <1.9.3, но больше не работает, и я хочу исправить. Выглядело это примерно так: </p>

module MyThing
  def self.do_something
    ...
  end
end

... и допускается для:

MyThing.do_something

Я не пытаюсь утверждать, что этот дизайн был хорошим - просто пытаюсь выяснить, как лучше всего это исправить. Склоняясь к стандартному модулю ...

Обновление ...

Я неправильно упростил мою проблему и пример. Различное поведение, которое я испытываю, проявляется во время моих тестов RSpec - они проходят с использованием RSpec 2.8.0 с MRI 1.9.2, но терпят неудачу с MRI 1.9.3. Модуль выглядит так:

module MyThing
  module SubThing
    module SubSubThing
      def self.do_something
        ...
      end
    end
  end
end

... и тесты:

describe MyThing::SubThing::SubSubThing do
  include MyThing::SubThing

  describe "#do_something" do
    it "does something" do
      SubSubThing.do_something
    end
  end
end

При запуске спецификации под 1.9.3 я получаю NameError: uninitialized constant DataGathering; под 1.9.2 они проходят. Это привело меня к неправильной диагностике проблемы и представлению того, что я сделал выше. Кажется, что include поведение отличается в 1.9.3. Все в порядке; мой вопрос все еще стоит: #module_function предоставляет что-то особенное?

Ответы [ 2 ]

3 голосов
/ 14 февраля 2012

Цель module_function - это именно то, что вы упомянули в своем вопросе: она дает вам возможность явно вызывать методы класса в модуле, используя имя модуля, или смешивать его и делать вещи более краткими..

Вы также можете сделать то же самое с extend self (внутри определения модуля).Разница в том, что если вы смешиваете в модуле, который использует module_function, смешанные методы станут приватными методами экземпляра (но они будут методами открытого класса декларирующего модуля);если вы используете extend self, они будут иметь любой квалификатор доступа, использованный в определении модуля, и при смешивании и при вызове непосредственно в модуле как методы класса.

0 голосов
/ 13 февраля 2012

Модуль в Ruby абстрактно эквивалентен пространству имен в C ++. Это должно быть хорошо для Ruby 1.9.3:

module MyThing
   def MyThing.do_something
      # ...
   end
end

do_something также может быть реализован как метод экземпляра MyThing, где все становится мутно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...