2010-10-03 2 views
9

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

спасибо

+0

Почему они должны? Включение модуля - это не то же самое, что наследование класса. –

+0

@Mladen, я не покупаю это. Если концептуальное различие было настолько ясным, то почему люди (даже очень топ-программисты на Ruby) пытаются обойти это ограничение, используя «ClassMethods' hack? Далее - почему это так кажется, что каким-то образом характер модуля подразумевает * это * особое ограничение. – horseyguy

+0

IMHO, модуль mixins! = Множественное наследование, так что, что бы ни делали некоторые люди, на самом деле ничего не доказывает. BTW, можете ли вы проиллюстрировать необходимость взлома на примере реального мира, где, например, не удалось достичь такого же результата, включив модуль 'A' и расширяя модуль' B'? –

ответ

0

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

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

+0

методы singleton могут использоваться гораздо больше, чем создание объектов; Я не думаю, что это может быть причиной, но спасибо :) – horseyguy

1

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

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

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

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