2013-03-13 2 views
0

Может ли кто-нибудь помочь мне понять нижеприведенные 3 метода их функциональных различий и функциональных возможностей ?Модуль № включительно и модуль № расширенный и модуль # предшествующие сравнительные обсуждения

  • Модуль # включен: mod.included (другой) вызывается после other.include (мод)

  • Модуль # расширенный: mod.extended (obj) вызывается после obj.extend (mod)

  • Модуль # предваряется: mod.prepended (другой) вызывается после other.prepend (мод)

Может ли один пример можно использовать для понимания выше трех сравнительно?

Thanks

ответ

1

В рубине. вы можете включить модуль в другой класс, и методы будут доступны для экземпляров этого класса. Расширение аналогично, за исключением того, что методы добавляются в класс как методы класса. More info here или here.

Prepend - это новая функция 2.0. «Иногда вам нужен метод из модуля, чтобы использовать приоритет для метода из класса. Существуют некоторые решения для выполнения этой задачи, такие как alias_method_chain, но это скорее взлом, чем что-либо - и не очень безопасный». - То есть вы иногда хотите, чтобы методы, которые вы включаете, были помещены перед методами внутри класса, и затем вы можете использовать super для вызова исходных методов внутри класса.

Оба эти соединения имеют подробные примеры, поэтому не забудьте проверить их. Но для того, что включено, добавлено и расширено? Ну, в модуле, который вы хотите включить/продлить/добавить, вы можете определить эти функции, и когда произойдет фактическое включение/расширение/добавление, этот метод будет вызван с параметром obj, установленным для класса, который вы расширяете. Это полезно, например, когда вы не хотите добавлять только методы в класс, но хотите добавить к нему такие вещи, как переменные класса или переменные экземпляра, или инициализировать значения ... бесконечные возможности.

Пример

Скажем, у меня есть тонны моделей, как комментарий, сообщение, изображения и т.д. Вместо того, чтобы скопировать и вставить тот же код для реализации функции, как, например, способность к «как "вещь, я могу вместо этого создать что-то вроде этого:

module Likable 
    def self.included(obj) 
    obj.instance_variable_set(:@like_count, 0) 
    end 
end 

class Comment 
    include Likable 
end 

class Picture 
    include Likable 
end 

Как вы можете видеть, это автоматически устанавливает новый переменный экземпляр с именем like_count 0. конечно, я хотел бы добавить больше коды, но суть здесь вы извлекаете часть функциональности в модуль многократного использования, который вы используете n затем позже помещается в несколько разных классов.Это иногда используется, даже если вы добавляете функциональность только к одному классу, поскольку преимущество этого заключается в том, что определенная функция извлекается в отдельный класс, и вы можете понять и настроить код намного проще, чем если бы он был смешан с другими функциями ,

+0

Спасибо за развернутую помощь :) –

1

Module#prepended хорошо описывается here наряду с другими новыми функциями в Рубине 2,0

Module#included и Module#extended работы аналогичным образом, как include и extend

Вот популярная модель, которая используется в проекте Rails:

module Talker 

    def self.included(base) 
    base.extend ClassMethods 
    end 

    module ClassMethods 
    def say(*args) 
     args.each do |arg| 
     method_name = ("say_" + arg.to_s).to_sym 
     send :define_method, method_name do 
      puts arg 
     end 
     end 
    end 
    end 

end 

included is hook on include мероприятие (sam e как extended на extend), он вызывает, когда модуль Talker включен в другой класс.

По этой функции мы можем расширить исходный класс вместо этого шаблона:

class Original 
    include Talker 
    extend Talker::ClassMethods 
    ... 
end 
+0

вы сделали много .. но мой толстый мозг, просто хотели бы просить Вас , можно ли объяснить три концепции одним примером? :) –