刚才在看去年的RailsConf上 Wilson Bilkovich的关于Rubinius的访谈。他提到有些他以为会很容易实现的东西结果异常困难,然后举了个默认参数与lambda组合使用的例子。据说是Ola提出的test case,hmm。
我突然兴奋,暂停了视频播放,打开irb然后玩了一下:
>irb irb(main):001:0> def foo( x = 5, y = lambda { puts x } ) irb(main):002:1> y.call irb(main):003:1> end => nil irb(main):004:0> foo 5 => nil irb(main):005:0> i = 2 irb(main):006:0* foo i, lambda { puts i + 1 } 3 => nil irb(main):007:0> foo 1 1 => nil
看上去确实没什么,很直观的语言构造。不过稍微想象这东西要如何实现,一下全身鸡皮都起来了 =_=|| 主要上面的实验里还没把闭包的真正威力用出来。让我们来看看:
>irb irb(main):001:0> x = 1 => 1 irb(main):002:0> def foo( x, y = lambda { |x| x *= 5 } ) irb(main):003:1> x += 1 irb(main):004:1> y.call x irb(main):005:1> x irb(main):006:1> end => nil irb(main):007:0> foo 1 => 10 irb(main):008:0> x => 1 irb(main):009:0> foo x => 10 irb(main):010:0> x => 1 irb(main):011:0> foo x, lambda { |x| x *= 5 } => 2 irb(main):012:0> x => 10
虽然还是很正确很明白的Ruby代码……可是要把这“此x非彼x”关系弄明白真是麻烦。不过在默认参数里放闭包这种事情我还真是没想过。
Wilson提到的问题是他们对局部变量的处理问题吧。大概参数y声明的时候,局部变量还没分配空间之类的问题,然后那个block就不知道捕获哪里的x好。后来似乎是通过修改局部变量的分配方式来解决。
回头我得拿DolphinScript来实验下看看是不是会有奇怪的事情发生才行。