如何从Ruby中的实例方法访问模块



假设我有一个模块:

module M
  def self.foo
    ...
  end
  def bar
    ...
  end
end

模块M包括在类中。

class A
  include M
end

我想从bar调用foo,最终将在A实例上调用。在bar内执行此操作的最佳方法是什么?

当然我只能说M.foo,但这是该模块名称的重复,这感觉不需要。

通常,在module中,最好将类方法和实例方法分开是一个好习惯:

module M
  def bar
    puts "BAR"
    self.class.foo
  end
  module ClassMethods
    def foo
      puts "FOO"
    end
  end
end

现在,在一堂课中,我理想地希望以一种将A.foo作为类方法和A.new.bar作为实例方法的方式来 include CC_8。诀窍是Module.included

module M
  def bar
    puts "BAR"
    self.class.foo
  end
  module ClassMethods
    def foo
      puts "FOO"
    end
  end
  # when module is included, extend the class with ClassMethods
  def self.included(base)
    base.extend ClassMethods
  end
end
class A
  include M
end
A.singleton_methods #=> [:foo]
A.new.foo
#=> BAR
#=> FOO

使用这种方法,您可以使用self.class引用类方法,并且可以自动起作用。

希望它有帮助。

不是真正优雅,而是

def bar
  Module.nesting.last.foo
end

应该这样做。

请注意,Module#nesting返回数组,因为一个模块可能嵌套在另一个模块中。在一般情况下,您需要应用正确的数组索引来选择要拥有的模块。

我认为使用M.foo是最好的,但是作为练习,可以更改M#bar如下。

module M
  def self.foo
    puts "In self.foo"
  end
  def bar
    puts "In bar"
    method(__method__).owner.foo
  end
end
class A
  include M
end
a = A.new
a.bar
  # In bar
  # In self.foo

最新更新