包含模块时使用间接寻址是否有优势(7周内使用7种语言,Ruby第3天)
Bruce在Ruby day 3第38页的“七周七种语言”中给出了以下示例:包含模块时使用间接寻址是否有优势(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
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。