2

使用模块扩展对象实例时遇到一些麻烦,特别是当我在 Module 类中定义 extend_object 回调时。我的理解是,当您执行以下操作时:

(s = String.new).extend SomeModule

调用 SomeModule extend_object 回调。情况似乎是这样,但是当我包含回调时, SomeModule 中定义的实例方法在对象中都不可见。一些代码应该更好地解释这一点:

module M1
  def self.extend_object(o)
  end

  def test_method
    true
  end
end

module M2
  def test_method
    true
  end
end

(x = String.new).extend(M1)
(y = String.new).extend(M2)

然后,

x.methods.include?("test_method")
=> false
y.methods.include?("test_method")
=> true

进一步来说,

x.singleton_methods
=> []
y.singleton_methods
=> ["test_method"]

有任何想法吗?

参考:

http://www.ruby-doc.org/core/classes/Module.html#M001660
http://www.ruby-doc.org/core/classes/Object.html#M000337
4

3 回答 3

10

您应该使用extended回调而不是覆盖extend_object. 第一个在您的模块扩展对象时调用。调用后者来实际扩展对象。included这就像和之间的区别append_features

这是一个例子:

module M1
  def self.extended(base)
    puts "extended object #{base.inspect}"
  end

  def test_method
    true
  end
end

然后:

>> (x = String.new).extend(M1)
extended object ""
=> ""

>> x.methods.include?("test_method")
=> true
于 2009-05-22T10:05:22.827 回答
3

从同事那里得到了一些帮助,并意识到我需要打电话给super其他人,这是一个问题。谢谢。

于 2009-05-22T07:37:37.383 回答
0

您还需要使用符号,因为方法名称是符号

module M1
  def self.extend_object(o)
    super
  end

  def test_method
    true
  end
end

(x = String.new).extend(M1)

x.methods.include?(:test_method)  #=> true
于 2012-04-29T14:50:39.073 回答