默认参数与闭包的组合

阅读更多
还从来没想过或者写过这么麻烦的东西,天啊。
刚才在看去年的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来实验下看看是不是会有奇怪的事情发生才行。

你可能感兴趣的:(Ruby)