-1

假设我有一个模块:

module M
  def self.foo
    ...
  end

  def bar
    ...
  end
end

模块M包含在一个类中。

class A
  include M
end

我想从 调用foobar最终将在 的实例上调用A。在里面做这个的最好方法是什么bar

当然我只能说M.foo,但那是模块名称的重复,感觉没有必要。

4

3 回答 3

1

通常,在 amodule中,将类方法和实例方法分开是一个好习惯,如下所示:

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

  module ClassMethods
    def foo
      puts "FOO"
    end
  end
end

现在,在一个类中,理想情况下,我希望include这个模块M以我A.foo作为类方法和A.new.bar实例方法的方式获得。诀窍是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它会自动工作。

希望能帮助到你。

于 2017-09-05T06:50:28.527 回答
0

不是很优雅,但是

def bar
  Module.nesting.last.foo
end

应该这样做。

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

于 2017-09-05T06:23:01.233 回答
0

我认为使用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
于 2017-09-05T07:11:48.810 回答