方法不知道外部变量?

时间:2013-09-28 21:16:32

标签: ruby scope local-variables

假设我正在编写一个除法算法脚本:

def current_trace
  puts "Counter: #{counter}; r: #{r}; q: #{q}"
end

r = a
q = 0
counter = 0

while r >= d
  current_trace
  r = r - d
  q = q + 1
  counter += 1
end
current_trace

我希望调用current_trace会输出counterrq的值。但我得到了:

  对于main:Object(NameError)

,在current_trace': undefined local variable or method counter'中

  1. 这里有什么问题?
  2. 我应该如何编写一个方法,在任何给定点输出名为counterrq的变量的值(最好不要将参数传递给方法) ?

3 个答案:

答案 0 :(得分:2)

在这种情况下,您的current_trace方法非常简单,不值得将其作为方法。但是看看你的代码,你这样做的原因可能是因为它不止一次出现。这是应该改进的代码中不好的部分。通过重新考虑条件和puts的时间安排,您可以避免在两个不同的位置拨打puts

counter, q, r = 0, 0, a
loop do
  puts "Counter: #{counter}; q: #{q}; r: #{r}"
  break if r < d
  counter += 1
  q += 1
  r -= d
end

答案 1 :(得分:1)

正确的做法是编写方法,使其接受参数:

def current_trace(c, r, q)
  puts "Counter: #{ c }; r: #{ r }; q: #{ q }"
end

然后称之为:

d = 1          
r = 5          
q = 0          
counter = 0    

while r >= d                      
  current_trace(counter, r, q)    
  r = r - d                       
  q = q + 1                       
  counter += 1                    
end                               

current_trace(counter, r, q) 

结果是:

Counter: 0; r: 5; q: 0
Counter: 1; r: 4; q: 1
Counter: 2; r: 3; q: 2
Counter: 3; r: 2; q: 3
Counter: 4; r: 1; q: 4
Counter: 5; r: 0; q: 5

(我调整了你的变量名,因为你的代码不起作用,因为你没有显示ad来自哪里,但那不是重点。)

您可以使用@instance$globalCONSTANTs,但这些游戏会使用变量作用域进行游戏,当您在某些方法中意外更改它们时会导致问题,通常是因为您输错了它们或者离开sigil(@$)并无意中创建一个不会改变你想要的变量的局部变量。必须在主要级别使用@var$var,只是为了让您的代码正常工作,这是一个很好的迹象,表明您实际上做错了。

答案 2 :(得分:-2)

我想我明白了。 counterrq(显然)仅在main的范围内。我将它们更改为全局$counter$r$q,现在我可以在我的方法中访问它们。

(在此实现:https://stackoverflow.com/a/9389532/1468130