2
class A
  def numbers
    [1,2,3,4]
  end

  def get_numbers(condition)
    numbers = [3,5] if condition
    numbers
  end
end

a = A.new
a.get_numbers(true) # [3,5]
a.get_numbers(false) # nil

我希望它会[1,2,3,4]在第二种情况下返回!

PS我不是在寻找解决方案(我只能有两个不同的变量名来解决我的问题),而是在寻找这种行为的解释,ruby是否在运行时本身创建变量并因为条件而numbers初始化?nilif

4

2 回答 2

7

当令牌可以被解释为局部变量或方法调用时,局部变量具有优先权。方法定义中的最后一个numbers被解释为局部变量。要将其解释为方法调用,您需要使其明确。

这可能是您的意图:

def get_numbers(condition)
  return numbers = [3,5] if condition
  numbers()
end

但这是很臭的代码,应该是这样的:

def get_numbers(condition)
  condition ? [3,5] : numbers
end
  • ruby 是否numbers在运行时本身创建 [create] 变量并 [and] 初始化 [initialize it]nil因为if条件?

是的。无论条件是否满足,Ruby 都会解析所有内容,如果局部变量因为条件不满足而未赋值,则将其初始化为nil.

于 2013-07-20T09:27:08.513 回答
3

@sawa 有答案,但我建议对代码进行一些不同的更改。我会从:

def get_numbers(condition)
  numbers = [3,5] if condition
  numbers
end

到:

def get_numbers(condition)
  return [3,5] if condition
  numbers()
end

我喜欢保持简单并且代码很明显。对局部变量的赋值什么也没做,并且使用没有空括号的方法名称会混淆/隐藏它是一个方法调用。


完全可以接受的另一种编写代码的方法是:

def get_numbers(condition)
  if condition
    return [3,5] 
  else
    numbers()
  end
end

甚至:

def get_numbers(condition)
  if condition
    [3,5] 
  else
    numbers()
  end
end

编写代码不仅是为了得到正确的答案,而且还在于能够在六个月或一年内返回它,而无需花费数小时试图记住你做了什么,或者更糟的是,你为什么这样做。其他人继承了我们的代码,因此我们需要对当我们写得不清晰、干净和简洁时可能在他们脑海中造成的破坏保持敏感。

于 2013-07-20T14:42:06.710 回答