1
module Ext
  refine Hash do
    def foo
      puts :in_foo
    end
    def bar
      puts :in_bar
      foo
    end
  end
end
module Test
  using Ext
  Hash.new.bar
end
# in_bar
# in_foo
# => nil

这按预期工作。但是,如果我想在和之间共享foobar使用HashArrayinclude会失败。

module Shared
  def foo
    puts :in_foo
  end
  def bar
    puts :in_bar
    foo
  end
end
module Ext
  refine Hash do
    include Shared
  end
  refine Array do
    include Shared
  end
end
module Test
  using Ext
  Hash.new.bar
end
# in_bar
# NameError: undefined local variable or method `foo' for {}:Hash

有没有办法在改进之间共享代码?

4

1 回答 1

0

问题不在于分享。完全摆脱Array细化,你会产生相同的行为。

根据文档

细化一直有效,直到文件结束或 eval 字符串结束。细化在范围上是词法的。当控制转移到范围之外时,细化被停用。这意味着如果您需要或加载文件或调用在当前范围之外定义的方法,则优化将被停用。

也就是说,您的示例中失败的是refine do ⇒ include. 语言还没有准备好理解include里面的refine子句。也许将来有可能,届时该功能将退出“实验”阶段。

如果你仍然认为你想依赖细化,你可能会欺骗 ruby​​(全局是为了清晰起见):

$ref = lambda do
  def foo
    puts :in_foo
  end
  public :foo
  def bar
    puts :in_bar
    foo
  end
  public :bar
end
module Ext
  refine ::Hash do
    $ref.call
  end
end
module Test
  using Ext
  ::Hash.new.bar
end

#⇒ in_bar
#⇒ in_foo
于 2015-06-28T10:41:08.360 回答