2013-04-03 68 views
3

我想弄清楚的Ruby如何处理具有相同的名称为self类的方法的局部变量,并发现了一个行为,我不明白:方法的局部变量同名的另一种方法

class A 
    def val 
    10 
    end 

    def test 
    val = val 
    end 
end 

p A.new.test 

此代码打印nil。为什么?!

+0

方法'val'是一个红色的鲱鱼。你从来没有真的叫它。 –

+0

类似的方法和它内部的变量具有相同的名称:http://stackoverflow.com/questions/8174019/what-happens-with-this-method-name-local-variable-mixing,外部变量:http: //stackoverflow.com/questions/3741582/method-and-variable-name-is-the-same –

回答

3

我认为局部变量一旦被声明就会被声明。在ruby中,查找首先查找局部变量,如果它存在,则使用该变量,否则查找方法。这意味着,VAL = VAL宣布第一VAL当地和左手VAL然后与它匹配(不知道它,我应该检查ruby under microscope,以确保)

如果您尝试

class A 
    def val 
    10 
    end 

    def test 
    back = [] 
    x = val 
    back << x 
    val = x + 1 
    back << val 
    x = val 
    back << x 
    end 
end 

p A.new.test 

那么一切都很好,它会打印[10,11,11],这意味着第一个x = val调用该方法,第二个调用局部变量,据推测。

+0

谢谢。这是一个合理的解释。它也解释了为什么它不会在'val = val'中引发异常。 – akonsu

0

这是nil,因为val是你试图传递的方法,你不会在任何地方调用val,并且它会覆盖自身。基本上你陷入循环。

在每个函数的末尾有一个隐式返回,它返回最后一个值,如果它没有返回值,Ruby返回nil,但是你可能期待一个函数?

这与Python类似,其中没有返回的函数总是返回None

这可以通过将的内涵将左手val转换为实例属性来解决。

我猜你想要它打印10使用val()方法?

def test 
    @val = val() 
end 

puts A.new.test 

下面是同样有效:

def test 
    val = self.val() #but this will produce the same as above to no real benefit. 
end 

,关键在于你必须调用val方法,以使val变量来获取值。

+0

谢谢。我不会说我因为程序终止而陷入循环。我期待'10',而不是一个功能。这肯定与括号有关。如果我的'test'方法只有一行'val',那么它返回'10'。但对我来说,令人困惑的部分是这项任务导致'val'成为'nil'。 – akonsu

+0

不是,它更多的是与你试图告诉Ruby“val”本身有关。这导致了Ruby无法找出你想要的循环。 –

+0

没有循环。该程序终止。我很困惑。 – akonsu

0

这应分成两个问题:

  1. 当你a = a,什么是第一次评估?如果你做echo 'p a = a' | ruby,你会得到nil,而不是未定义的异常,所以定义是第一位的。

  2. 当局部变量与方法名称相同时会发生什么?答案:除非您使用方法,否则方法变得不可见self.

相关问题