鉴于这个简单的Ruby代码:
def testMethod
testVar = 1
def subTestMethod
if testVar == 1
puts 'Yes'
else
puts 'No'
end
end
subTestMethod
end
testMethod
有没有办法将本地testVar
变量传递给子方法而不必强制使用类变量?
答案 0 :(得分:8)
你拥有的代码很可能没有你想做的事情:
代码中的内部def
不定义本地方法。相反,只要subTextMethod
类首次调用Object
,它就会将testMethod
定义为全局方法。这意味着在您调用testMethod之后,您将能够从任何地方调用subTestMethod
。
subTestMethod
当前不属于testMethod
,这也意味着subTestMethod
无法关闭testMethod
的本地变量。
要获得所需的行为,您可能希望使用这样的lambda(或重新考虑您的设计,以便您不需要任何嵌套函数):
def testMethod
testVar = 1
subTestLambda = lambda do
if testVar == 1
puts 'Yes'
else
puts 'No'
end
end
subTestLambda.call
end
答案 1 :(得分:5)
在Ruby中,只有块(和lambda文字)可以是闭包。因此,您必须使用块来定义方法:
def testMethod
testVar = 1
Object.send(:define_method, :subTestMethod) do
if testVar == 1
puts 'Yes'
else
puts 'No'
end
end
subTestMethod
end
testMethod
正如其他人已经指出的那样,这是否符合你的想法,当然取决于你认为它的确切 ,但很可能,它不< / em>的
只有几个样式提示:方法和(非常量)变量遵循snake_case
命名约定,使用空行将初始化与实际工作和返回值分开,一切都是表达式。
因此,您的testMethod
,subTestMethod
和testVar
应该命名为test_method
,sub_test_method
和test_var
。在define_method
之前和sub_test_method
之前应该有一个空行。您可以将puts
拉出if
表达式,因为 表达式因此返回其值:
def test_method
test_var = 1
Object.send(:define_method, :sub_test_method) do
puts(if test_var == 1 then 'Yes' else 'No' end)
end
sub_test_method
end
test_method
你可能更想要的是一个lambda:
def test_method
test_var = 1
sub_test_lambda = -> { puts(if test_var == 1 then 'Yes' else 'No' end) }
sub_test_lambda.()
end
test_method
答案 2 :(得分:1)
将testVar
作为参数传递给subTestMethod
def testMethod
testVar = 1
def subTestMethod(testVar)
if testVar == 1
puts 'Yes'
else
puts 'No'
end
end
subTestMethod testVar
end