Ruby extend module 的方法

fsword · 2012年12月05日 · 最后由 luikore 回复于 2012年12月06日 · 4229 次阅读

只是发帖确认一下,下面两种应该是等价吧,我常用第一种,今天在 i18n 的库里看到了第二种

module X
  extend self
  def hello; 'hello'; end
  def world; 'world'; end
end
module X
  extend Module.new {
    def hello; 'hello'; end
    def world; 'world'; end
  }
end

明白为什么这么写了,自问自答一下:前一种支持直接 include X,然后调用内部方法,后一种避免了 include 以后污染当前变量空间

1.9.3p327 :001 > module X
1.9.3p327 :002?>     extend Module.new {
1.9.3p327 :003 >           def hello; 'hello'; end
1.9.3p327 :004?>         def world; 'world'; end
1.9.3p327 :005?>       }
1.9.3p327 :006?>   end
 => X 
1.9.3p327 :007 > X.hello
 => "hello" 
1.9.3p327 :008 > include X
 => Object 
1.9.3p327 :009 > hello
NameError: undefined local variable or method `hello' for main:Object
    from (irb):9
    from /home/john/.rvm/rubies/ruby-1.9.3-p327-falcon/bin/irb:16:in `<main>'

有区别的。前者还可以 include。后者是一个匿名的内部模块。

其实一般这么用就可以了...

module X
  module_function
  def hello; 'hello'; end
  def world; 'world'; end
end

#3 楼 @luikore 试了一下,module_function 大概等价于 extend self,不能用来避免 include 后的污染,不过这个实现怎么是 c 代码,有什么特别吗?

#4 楼 @fsword 哦果然也是污染的... 就是 include 以后这些方法变成 private 了而已

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