0

任何人都可以帮助我了解以下 3 种有关其功能差异和用途的方法吗?

  • Module#included : mod.included(other)other.include(mod)之后调用

  • Module#extended : mod.extended(obj)obj.extend(mod)之后调用

  • Module# prepended : mod.prepend(other)other.prepend(mod)之后调用

可以用一个例子来比较理解以上三者吗?

谢谢

4

2 回答 2

1

在红宝石中。您可以将一个模块包含到另一个类中,并且这些方法将可用于该类的实例。Extend 类似,只是方法作为类方法添加到该类。更多信息在这里这里

Prepend是 2.0 的新功能。“有时,您希望模块中的方法优先于类中的方法。有一些解决方案可以完成此任务,例如 alias_method_chain,但它比任何东西都更像是一种 hack - 而且并不安全。” -- 也就是说,有时您希望将包含的方法放在类中的方法之前,然后您可以使用它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_count0 的新实例变量设置为几个不同的班级。即使您只向单个类添加功能,有时也会使用此功能,因为这样做的好处是某个功能被提取到单独的类中,您可以比将代码与其他功能混合更容易理解和调整代码.

于 2013-03-13T14:18:17.253 回答
1

Module#prepended在这里很好地描述了 Ruby 2.0 中的另一个新特性

Module#included并以与和Module#extended类似的方式工作includeextend

这是 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是挂钩事件(与oninclude相同),它在模块包含到另一个类时调用。extendedextendTalker

通过这个功能,我们可以扩展原始类而不是这种模式:

class Original
  include Talker
  extend Talker::ClassMethods
  ...
end
于 2013-03-13T18:15:36.503 回答