Почему включение модуля Ruby исключает одноэлементный класс модуля? - PullRequest
9 голосов
/ 03 октября 2010

Когда классы наследуются в Ruby, наследуемые классы также наследуются:

class A
  def self.hello
    puts "hello"
  end
end

class B < A
end

B.hello #=> "hello"

Тем не менее, с модулями это не так:

module M
  def self.goodbye
    puts "goodbye"
  end
end

class A
  include M
end

A.goodbye #=> NameError

Чтобы обойти это ограничение, многие люди прибегают к этому уродливому хаку:

module M
  def self.included(c)
    c.extend ClassMethods
  end

  module ClassMethods
    def goodbye
      puts "goodbye"
    end
  end
end

Итак, мой вопрос: есть ли теоретическая / концептуальная причина этого ограничения для модулей? или это просто сложность реализации?

Посмотрев на исходный код C (YARV / MRI), я могу определить, есть ли сложности в реализации (не непреодолимые, но все же одинаковые), но единственная ли это причина? Есть ли другие причины для такого ограничения?

спасибо

Ответы [ 2 ]

1 голос
/ 04 октября 2010

Если кто-то не может выдвинуть убедительный аргумент, я чувствую, что ограничение сводится только к сложности реализации. Тем не менее, я работал над этой проблемой последние пару дней и имею (в бета-версии) новую версию include под названием include_complete, которая обходит эти трудности и позволяет наследованию модулей работать так же, как наследование классов (добавляя синглтон)

Проверьте проект здесь: http://github.com/banister/include_complete

И будьте осторожны, проект все еще находится в стадии бета-тестирования, но, похоже, до сих пор работает так, как хотелось бы

0 голосов
/ 03 октября 2010

Предупреждение: ниже приведено только предположение.

Если вы используете класс, вам понадобятся одноэлементные методы класса, потому что вы полагаетесь на них для создания объекта (например, MyClass.new).Если вы используете модуль, он вам не нужен, потому что вы не можете создавать объекты исключительно из модуля.

...