新手问题 Monkey Patch 的作用域

Alexander · 2013年03月09日 · 最后由 Alexander 回复于 2013年03月10日 · 2595 次阅读

如这段代码:

module A
  class ::String
    def add_by_module_a
      'hello world'
    end
  end
end

我预期只有在 include A 的作用域里面, String 才会被扩展, 而实际上, 却不是如此. 请问要如何实现我的预期呢, 还是实现不了?

btw: 之前好像听闻 Ruby2 有这方面的的打算, 但看 What's new 没有发现这个特性呀. 还是我记错了.

Ruby 2 实现了一个新的语法叫做 using, 的确是你想要的功能, 不过貌似有较大的 bug, 在 Ruby 2.0 p0 中,只是作为一个实验性的尝试.

include A 混入的是 A 里面定义的实例方法. 你搞错了 include 的含义.

#1 楼 @zw963 thx. 不过我觉的我的那种预期语义是 "不使人惊讶" 的 :-), 为什么不使用这个语法而额外的添加新的语法呢? lol

因为根本是两个概念呀.

Ruby 中至少到现在为止, 不存在所谓的 包管理 ?? 你要是直接 hack 了一个核心类, 则每一个应用都会受到影响, 这就是常说的 Ruby 不适合大规模开发 所诟病的东西, refinement 就是在试图改善这个印象, 将可影响的范围降到一个局部. 不过 Ruby 2.0 p0 里面, 这个特性还只是一个玩具...


module FooBar
  refine String do
    def hello
      puts "Hello, world"
    end
  end
end

"str".hello     # => No Method Error
using FooBar    
"str".hello     # => "Hello world"

#3 楼 @zw963 是的, 谢谢你耐心的, 友好的回答. 😄

需要 登录 后方可回复, 如果你还没有账号请 注册新账号