Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Ruby中,如何从正在扩展的模块应用attr_访问器?_Ruby - Fatal编程技术网

在Ruby中,如何从正在扩展的模块应用attr_访问器?

在Ruby中,如何从正在扩展的模块应用attr_访问器?,ruby,Ruby,我正试图通过将方法组织成单独的模块来模块化一些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_

我正试图通过将方法组织成单独的模块来模块化一些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
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
我试过这样做:

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
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
但是,不工作的部分是
attr\u访问器
。我已经尝试了
include
/
extend
def self.include(base)的所有不同组合;base.extend
,而我似乎找不到合适的组合来让所有东西协同工作。我该怎么做


更新:我想我遗漏的部分是,每个模块都可能同时具有实例方法和类方法。所以我现在有这样的东西:

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
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
类。

以正确获得您想要的功能,您必须将
extend
更改为
include
,并在模块中提供
included
块。这样,您就可以在一个模块中定义实例和类方法,只需
包含该模块并适当地组织您的方法

可能需要对代码进行一点重新组织,但为了帮助解释更多内容,您可以

如果仍然不清楚,您可能需要查看。

模块中定义,因此只能在模块和类(即模块)上调用。它通过调用将给定模块中的常量、(实例)方法和(模块)变量添加到接收方

另一方面,在
对象中定义,即不限于模块和类。它将给定模块中的实例方法添加到接收方,或者更准确地说,添加到接收方的单例类中

下面是一个带有实例方法的示例模块
hello

module Mod
  def hello
    "Hello from #{self.class} '#{self}'"
  end
end
如果我们
扩展一个实例(与类相反),那么
hello
将成为一个实例方法:

如果我们扩展一个类,那么
hello
将成为一个类方法:

这是因为类方法实际上只是在类的单例类中定义的实例方法

也就是说,可以通过调用
extend
和/或
include
来定义类和实例方法:

1. <代码>扩展
包括
这是最基本的一个,您可以将
include Name
从Person移动到
Joe

module Person
  include Arms, Legs
end

class Joe
  extend Person
  include Name
end
2. <代码>扩展
在超类中包含
或者,您可以将
Person
创建为一个类,该类
扩展
s并
包含
s其他模块,并将其用作
Joe
的超类:

class Person
  extend Arms, Legs
  include Name
end

class Joe < Person
end
4. <代码>从包含的
中扩展
或者您可以从
Joe
包含Person
,并使用回调调用
extend

module Person
  include Name
  def self.included(mod)
    mod.extend Arms, Legs
  end
end

class Joe
  include Person
end

3和4从
Joe
内部看起来很干净,但是包含或扩展
Person
也定义了类或实例方法,这一点可能并不明显(甚至可能令人困惑)。如果我改为
include
,那么类方法将变成实例方法。对不起,我误解了。谢谢,这无疑使事情更容易理解。我想我遗漏的部分仍然有问题,那就是
Name
模块同时包含实例方法和类方法。我不认为
attr\u accessor
是一种实例方法,但它只在使用
include
时有效。因此,我只剩下尝试
包含Name::InstanceMethods
mod.extend Name::ClassMethods
了,但感觉很混乱。@Andrew您必须以某种方式
扩展类方法和
包含实例方法。也许有一种方法可以重组类/模块。