包含模块时使用间接寻址是否有优势(7周内使用7种语言,Ruby第3天)

包含模块时使用间接寻址是否有优势(7周内使用7种语言,Ruby第3天),ruby,inheritance,module,metaprogramming,Ruby,Inheritance,Module,Metaprogramming,Bruce在Ruby day 3第38页的“七周七种语言”中给出了以下示例: module ActsAsCsv def self.included(base) base.extend ClassMethods end module ClassMethods def acts_as_csv include InstanceMethods end end module InstanceMethods def read

Bruce在Ruby day 3第38页的“七周七种语言”中给出了以下示例:

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

  module ClassMethods
    def acts_as_csv
      include InstanceMethods
    end
  end

  module InstanceMethods
    def read
       #fill @csv_contents and @headers from file self.class.to_s.downcase + '.txt'
    end

    attr_accessor :headers, :csv_contents

    def initialize
      read
    end
  end
end

class RubyCsv
  include ActsAsCsv
  acts_as_csv
end

m = RubyCsv.new
puts m.headers.inspect
puts m.csv_contents.inspect
我看不出
def self.include(base)
ClassMethods
使用间接寻址的任何原因。与简单地包含模块InstanceMethods相比,上面的代码是否有优势


详细说明:“简单地包括模块实例方法”是指以下代码:

  module InstanceMethods #defined as above
    def read
       #fill @csv_contents and @headers from file self.class.to_s.downcase + '.txt'
    end

    attr_accessor :headers, :csv_contents

    def initialize
      read
    end    
  end

class RubyCsv
  include InstanceMethods
end

m = RubyCsv.new
puts m.headers.inspect
puts m.csv_contents.inspect

因为duck类型,这难道不等于通过
base.extend ClassMethods
执行吗?

原始代码允许您执行以下操作:

class A
  include ActsAsCsv
end

class B < A
  acts_as_csv
end
A类
包括ACTSASCV
结束
B类
虽然使用继承更多的是一个品味问题,但在这种情况下,如果

  • 更多的方法不仅仅是
    作为_csv
    被添加到
    A
  • actsascv
    将被一个类所包含,许多类都从该类继承(比如某种
    BaseModel

  • 方法
    作为_csv
    比仅包含
    实例方法
  • acts\u as\u csv
    接受一个参数,例如
    acts\u as\u csv:separator=>“”

一个优点是在代码(和原始编写者)和后来对代码进行推理的人之间进行目的交流。(以及允许参数的机制。)

作为csv
陈述了
RubyCsv
行为的一个方面

include actsascv
的声明性较低。它是否提供了额外的方法,是否从根本上改变了底层类的功能,或者两者都改变了,或者。。。?你看了文件才知道。您可能在阅读
acts\u asv\u csv
的文档之前不知道,但这更便于沟通

这就是“这就是我”和“这就是我可以做的”之间的区别。不要陷入具体的例子——考虑正在做的事情的机理,以及如何。


这种机制是Ruby代码看起来像它试图解决的问题而不仅仅是Ruby的原因之一。这是实现micro DSL的一种方法,有助于使Ruby尽可能具有表现力。

。因为这篇文章已经有将近一年没有被回复了(我被Stackoverflow的速度和质量给宠坏了:)而且这篇文章更全面,我希望没有人介意……它的优点是沟通。沟通?什么实体之间有什么信息?目的、代码和阅读代码的人之间有什么信息。附加代码和间接寻址如何使目的更具可读性?感谢obrok(+1)我编辑了您的答案,希望能让读者更清楚-希望我正确地解释了您的原因。你能给我一个到
BaseModel
的链接吗?@DaveBall没有
BaseModel
,这是一个基类的例子,可能包括
actsascv
,就像Rails模型包含允许
有很多
等的模块一样。哦,这就是我当时没有找到它的原因;)用于澄清的Thx。