何时在模块的方法中使用self

时间:2015-09-24 01:04:58

标签: ruby self

我的模块定义如下:

module RG::Stats
  def self.sum(a, args = {})
    a.inject(0){ |accum, i| accum + i }
  end
end

要使用此方法,我只需要包含此定义的文件,以便我可以执行:

RG::Stats.sum(array)

以及

RG::Stats.method(:sum)

但是,如果我需要知道使用RG::Stats.instance_methods的方法列表,我会得到一个空数组。这是因为我使用了self。如果我省略self,则RG::Stats.instance_methods会提供方法列表,但我无法再访问它们了。

问题是:如何在模块的方法定义中使用self

3 个答案:

答案 0 :(得分:13)

如果希望仅在模块的单例类中定义方法(使用self定义的方法实时),则在每个方法定义中使用self。如果希望将模块的方法同时定义为实例方法和单例方法,则省略self和extend self

例如,您可以使用RG::Stats.sum(array)调用该方法,如果您执行此操作,仍然可以使用instance_methods方法列出该方法:

module RG::Stats
  extend self

  def sum(a, args = {})
    a.inject(0){ |accum, i| accum + i }
  end
end

这样,sum方法被定义为实例方法,并在使用extend self后包含在模块的单例类中。

您可以检查RG::Stats模块的实例方法以验证这一点:

RG::Stats.instance_methods
=> [:sum]

使用这种技术,您不必担心在没有self关键字的情况下定义方法,因为模块不能拥有实例,因此无法像{{1}的实例方法那样调用它模块。由于RG::Stats语句,它只能被称为单例方法RG::Stats.sum(array)

答案 1 :(得分:3)

这是因为def self.sum没有定义实例方法;您使用错误的方法来选择它。试试这个:

RG::Stats.methods(false)
# => [:sum]

答案 2 :(得分:0)

如果您使用self,则可以直接使用模块方法:RG::Stats.sum(array),如上所述。

如果您不使用self来定义模块中的方法,那么对于包含模块的类,该方法将包含在instance_method中。

因此,您可以在sum模块中定义RG::Stats实例方法:

module RG::Stats
  def sum(a, args = {})
    a.inject(0){ |accum, i| accum + i }
  end
end

然后,您可以在类中包含RG::Stats模块,然后sum方法将作为instance_method用于该类的对象:

class YourClass
  include RG::Stats

  . . .
  . . .
end

您可以在sum的实例上调用YourClass方法:     YourClass.new.sum

要回答您的问题,您可以使用self将您的方法定义为模块内的类方法,而不使用self将方法定义为实例方法,这取决于您的需要和用例当你想要模块方法中的什么类型的行为时。