Ruby 又发现了个以前不知道的 Ruby 语法诶

ibachue · 2013年10月12日 · 最后由 luikore 回复于 2013年10月14日 · 4108 次阅读

Hi all,

这个语法是我在 Rails 里发现的:

def f
  Module.new &Proc.new
end

M = f do
  def self.x
    'hello world'
  end
end

M.x # => "Hello world"

事实上这个案例可以直接简化成:

def f
  Proc.new
end

(f { |name| 'hello, ' + name }).call 'bachue'
# => "hello, bachue"

原来Proc.new只要不传入 block 就默认自动接受其调用者的 block,这个语法我以前还真的没看到过诶。 不仅仅是Proc.newproc, lambda也类似,只是有时会出现警告而已,但依然可以工作。

super 也可以的

#1 楼 @luikore super可以我倒是知道的 毕竟本身也是个关键字,有点特殊语法不奇怪。Proc.new可以我就比较震惊了。

我也很震惊

第二种不能算是一个简化,它们是两个不同的实现。

1、返回的是个 Module,我不可以创建实例,可以 include,执行 module_exec 2、返回的是个 Proc 的实例。Proc.new,proc, lambda 它们只是本身有些区别。跟这个用法没关系了。

mark 一下:

3.2 (master) $ ack "Module.new" | ack "&Proc.new" activerecord/lib/active_record/associations/builder/collection_association.rb:27: extension = Module.new(&Proc.new)

Proc.new{ |name| "Hello, " + name  }.call 'Leslie'

#6 楼 @lmorenbit 我是从语法层面上讲得呀 去除与这个语法无关的部分 这样案例大家看得更加清楚点。

好玩。

什么样的场景要这样写,有什么好的地方?

#4 楼 @luikore 这个例子真好

#10 楼 @zhenjunluo 大概只算是语法糖吧 当你准备写类似于Proc.new { |*args| yield *args } proc { |*args| yield *args } lambda { |*args| yield *args }的时候,就可以写得简单点了。

用法很奇特

#12 楼 @iBachue 说语法糖其实不太恰当,parser 并没对这些代码做特殊处理,是语义的区别才对

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