如何将Ruby局部变量从方法传递给子方法?

时间:2010-12-30 20:49:41

标签: ruby variables

鉴于这个简单的Ruby代码:

def testMethod
  testVar = 1
  def subTestMethod
    if testVar == 1
      puts 'Yes'
    else
      puts 'No'
    end
  end
  subTestMethod
end

testMethod

有没有办法将本地testVar变量传递给子方法而不必强制使用类变量?

3 个答案:

答案 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命名约定,使用空行将初始化与实际工作和返回值分开,一切都是表达式。

因此,您的testMethodsubTestMethodtestVar应该命名为test_methodsub_test_methodtest_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