2013-10-24 3 views
3

를 다음 코드 나 문제를 일으키는 : Foo.new.incNoMethodError: undefined method '+' for nil:NilClassFoo.new.n 반환 0루비의 증가는 (+ =) 전무에 대한 오류 정의되지 않은 메서드를 '+'제기 NilClass

이유는 무엇입니까 호출 제기 호출

class Foo 
    def initialize(n=0) 
    @n = n 
    end 

    attr_accessor :n 

    def inc 
    n+=1 
    end 
end 

Foo.new.inc 오류를 제기 하시겠습니까? 나는 문제없이 Foo.new.n+=1을 할 수있다.

+1

그래서'@ n'을 사용 하시겠습니까? 아니면'자기. – Ryan

+1

'n + = x'는'n = n + x'로 확장됩니다. 여기서 * n은 왼쪽에 나타나므로 * n은 로컬 변수 *로 바인딩됩니다. – user2864740

답변

10

tldr; self.n = x의 일부 양식은 이어야하며 설정자에 항상을 할당해야합니다.

n += x는 그것이 할당 좌측에서 나타나기 때문에 N은 로컬 변수로 바인딩 n = n + x로 확장 것을 고려한다. 이 지역 변수의 "소개"는 암시 적 메서드 호출 (예 : n -> self.n)의 정상적인 후퇴 동작을 자체에 반하는 것입니다.

따라서 n 이후 (하지만 이제 로컬 변수로 바인딩이다 ) 아직 할당되지 않은, 식 는 예외를 발생시키는 원인이 무엇n = nil + x으로 평가한다.

+0

'n'에 할당하지 않았더라도 어디에서 읽으시겠습니까? 'ReferenceError'. –

+1

@JanDvorak 'n'이 * 할당 이전에 사용 된 경우 NameError가 발생합니다. 나는 틀린 마지막 절을 제거했다. – user2864740

+0

"암시 적 자체 메서드 호출의 일반적인 폴백 동작"- 참조하시기 바랍니다. 나는 이것이'커널'에서만 작동한다는 것을 확신한다. –

4

를 사용하여 귀하의 경우에는이

def inc 
    self.n += 1 
end 

또는이

def inc 
    @n += 1 
end 

는 알몸 이름은 "N"(존재하지 않는) 지역 변수로 해석됩니다. 명시 적으로 메소드 (self.n)이거나 기본 인스턴스 변수를 사용하도록 지정해야합니다.

+0

'self.n'는'@n'이 독자와 작가를 가지고 있고 (예상대로 행동한다면) 작동합니다. 후자의 형식이 선호되는 것으로 가정합니다. –

+1

@JanDvorak :'attr_accessor'는 그렇게합니다. – Ryan

+1

이 경우 독자가 있습니다. –

관련 문제