在Ruby中,如何从正在扩展的模块中应用attr_accessor?
我试图通过将方法组织成单独的模块来模块化一些
Ruby代码.最初我有这样的事情:
class Joe attr_accessor :name def self.arms 2 end def self.legs 2 end end 我尝试过这样的事情: class Joe extend Person end module Person include Name include Arms include Legs end module Name attr_accessor :name end module Arms def arms 2 end end module Legs def legs 2 end end 但是,无效的部分是attr_accessor.我尝试了include / extend,def self.included(base)的所有不同组合; base.extend我似乎无法找到合适的组合来使一切都协同工作.我怎样才能做到这一点? 更新:我认为我遗漏的部分是每个模块都可能有实例方法和类方法.所以我现在有这样的事情: class Joe include Person end module Person include Name::InstanceMethods include Arms::InstanceMethods include Legs::InstanceMethods def self.included(base) base.extend Name::ClassMethods base.extend Arms::ClassMethods base.extend Legs::ClassMethods end end module Name module ClassMethods; end module InstanceMethods attr_accessor :name end end module Arms module ClassMethods def arms 2 end end module InstanceMethods; end end module Legs module ClassMethods def legs 2 end end module InstanceMethods; end end 虽然这有效,但感觉很麻烦.它也像Person模块对实例方法和类方法了解得太多.如果我要修改Name模块以删除空/未使用的ClassMethods模块,我还必须修改Person类. 解决方法include 在Module中定义,因此只能在模块和类(模块)上调用.它通过调用
append_features 将常量,(实例)方法和(模块)变量从给定模块添加到接收器.
另一方面, 这是一个带有实例方法hello的示例模块: module Mod def hello "Hello from #{self.class} '#{self}'" end end 如果我们扩展一个实例(而不是一个类),那么hello将成为一个实例方法: str = 'abc' str.extend(Mod) str.hello #=> "Hello from String 'abc'" 如果我们扩展一个类,那么hello就成了一个类方法: String.extend(Mod) String.hello #=> "Hello from Class 'String'" 这是因为类方法实际上只是在类的单例类中定义的实例方法. 也就是说,有几个选项可以通过调用extend和/或include来定义类和实例方法: 1.扩展和包括 这是最基本的一个,您可以将包括姓名从人员移动到Joe: module Person include Arms,Legs end class Joe extend Person include Name end 2.扩展并包含在超类中 或者你可以使Person成为一个扩展并包含其他模块的类,并将其用作Joe的超类: class Person extend Arms,Legs include Name end class Joe < Person end 接下来的选项涉及一些Ruby魔法 – 他们使用回调来调用包含在扩展上,反之亦然: 3.包括扩展内容 您可以使用 module Person include Arms,Legs def self.extended(mod) mod.include(Name) end end class Joe extend Person end 4.从内包延伸 或者您可以在Joe中包含Person并使用 module Person include Name def self.included(mod) mod.extend Arms,Legs end end class Joe include Person end 从Joe内部看来,3和4看起来很干净,但是包含或扩展Person也可能不明显(甚至可能令人困惑?)也定义了类或实例方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |