如何将Ruby本地变量从一个方法传递到子方法?

3

假设有以下简单的Ruby代码:

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

testMethod

有没有办法在不强制使用类变量的情况下将本地变量 testVar 传递给子方法?

3个回答

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

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

正如其他人已经指出的那样,它是否能实现你想要的功能当然取决于你认为它做什么,但很可能它不会。

只是一些风格提示:方法和(非常量)变量遵循蛇形命名法,您使用空行将初始化与实际工作和返回值分开,并且所有内容都是表达式。

因此,您的testMethodsubTestMethodtestVar应该被命名为test_methodsub_test_methodtest_var。在define_methodsub_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

1
testVar作为参数传递给subTestMethod函数。
def testMethod
  testVar = 1
  def subTestMethod(testVar)
    if testVar == 1
      puts 'Yes'
    else
      puts 'No'
    end
  end
  subTestMethod testVar
end

请注意,这很可能不会产生Michael想要的行为,因为它仍然将subTestMethod定义为“全局”方法,而不是像在Python中那样定义为本地函数。 - sepp2k
是的,def将定义一个名为subTestMethod的新方法,可以像调用testMethod一样调用它。 - Chandra Patni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接