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

Roj*_*ojj 9 ruby self

我的模块定义如下所示:

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

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

RG::Stats.sum(array)
Run Code Online (Sandbox Code Playgroud)

并且

RG::Stats.method(:sum)
Run Code Online (Sandbox Code Playgroud)

但是,如果我需要知道使用的方法列表,RG::Stats.instance_methods我会获得一个空数组.这是因为我用过self.如果我省略self然后RG::Stats.instance_methods给出方法列表,但我不能再访问它们了.

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

iza*_*ban 15

self如果希望仅在模块的单例类中定义方法(使用selflive 定义的方法),请在每个方法定义中使用.省略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
Run Code Online (Sandbox Code Playgroud)

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

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

RG::Stats.instance_methods
=> [:sum]
Run Code Online (Sandbox Code Playgroud)

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


K M*_*lam 6

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

如果您self不习惯在模块内定义方法,则该方法将被包含instance_method在您包含该模块的类中。

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

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

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

class YourClass
  include RG::Stats

  . . .
  . . .
end
Run Code Online (Sandbox Code Playgroud)

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

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