Mic*_*rst 5 javascript ruby closures coffeescript
在CoffeeScript中:
f = ->
v = 5
g = ->
v
g()
f() # returns 5 as expected
Run Code Online (Sandbox Code Playgroud)
在Ruby中:
def f
v = 5
def g
v # undefined local variable or method `v' for main:Object (NameError)
end
g
end
f
Run Code Online (Sandbox Code Playgroud)
好吧,显然JavaScript函数被设置为捕获它们创建范围内的变量,但Ruby的方法却没有.有没有办法让Ruby方法在这方面像JavaScript函数一样?
Ruby具有脚本范围,模块/类/方法定义范围和块范围.只有块创建嵌套范围.因此,您需要使用块来定义方法.值得庆幸的是,有一种方法可以定义采用块的方法:
def f
v = 5
define_method :g do
v
end
g
end
f
# => 5
Run Code Online (Sandbox Code Playgroud)
但是,请注意,这并不会做你认为它(而且也没有你原来的代码).它没有定义g嵌套在方法中的方法f.Ruby没有嵌套方法.方法总是属于模块(类是模块),它们不属于方法.
这样做是定义一个方法f,当你运行它时定义一个方法g,然后调用该方法.
注意:
methods.include?(:g)
# => true
Run Code Online (Sandbox Code Playgroud)
您现在已经定义了一个新的顶级方法(实际上是一个私有实例方法Object)g,并且您将在每次f调用时反复定义它.
你可能想要的是一个lambda:
def f
v = 5
g = -> { v }
g.()
end
f
# => 5
Run Code Online (Sandbox Code Playgroud)
在对另一个答案的评论中写道:
好吧,所以我正在搞乱lambdas,我注意到我
v内心所做的任何事情g都没有反映在v一次g回归中.有没有办法让我的变化v坚持下去?
def f
v = 5
g = -> { v = 'Hello' }
g.()
v
end
f
# => 'Hello'
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,变化v 确实 "大棒"之后g的回报.
你没有在Ruby中定义方法内部的方法,但你可以使用lambda:
def f
v = 5
g = lambda do
v
end
g.call
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
814 次 |
| 最近记录: |