2014-12-03 2 views
3

위로 정기적으로 루비를 사용했을 때 나는 모든 것을 공개하고 개인 정보를 무시하는 나쁜 습관을 가지고있었습니다. 불행히도, 그 무지가 다시 나를 기다리고 있습니다.루비 개인 attr_accessor 및 예기치 않은 nil

0 
test.rb:13:in `test': undefined method `+' for nil:NilClass (NoMethodError) 
    from test.rb:19:in `<main>' 

그와 함께 무엇 :

class Something 
    private 
    attr_accessor :sneaky 
    public 

    def initialize 
     @sneaky = 0 
    end 

    def test 
     while sneaky < 10 
      puts "#{sneaky}" 
      sneaky = (sneaky + 1) 
     end 
    end 
end 

test = Something.new 
test.test 

이 교활한 (0)의 정확한 값을 출력 sneakynil 것을 말하고, sneaky = (sneaky + 1)에서 다음 오류를 : 여기에 내 문제의 간단한 버전입니까? @sneaky은 생성자에서 0으로 설정되었습니다. 그리고 실제로 그것이 0이라면, puts은 빈 줄을 인쇄하고 0을 인쇄해서는 안됩니까?

편집 : 그래, self.sneaky = sneaky + 1sneaky = (sneaky + 1) 교체는 명시 적 수신기를 가지고 있기 때문에 self.sneaky=은, 개인 정보 보호 위반과 같은 경우에도 문제를 해결한다. 명백하게 예외는 setter를 위해 만들어진다. 그러나 프라이버시와의 이상한 상호 작용은 test.rb:14:in 'test': private method 'sneaky' called for #<Something:0x000001019004c8 @sneaky=0> (NoMethodError)이된다는 뜻입니다. self.sneaky += 1이라고 말할 수는 없습니다. 다행히 나는 not the only one who thinks that's weird입니다.

답변

5

foo = bar의 형식은 foo이라는 로컬 변수에 할당됩니다. attr_writer으로 전화를 걸려면 명시적인 수신자 인 self.sneaky += 1을 사용해야합니다.

이 변수는 private과 아무 관련이 없습니다.이 변수는 로컬 변수 할당을위한 기본 Ruby 구문입니다.

+0

'private'는 이것이 private 접근 자이며, private 메소드는 일반적으로 명시 적 수신기를 사용하여 호출 될 수 없다는 점에서 관련이있다. 이런 이유로'self.sneaky + = 1'은 작동하지 않습니다. 그러나 '자기 몰래 = 몰래 한 + 1'은보기에 못생긴 다. 그래도 직관적 인 개인 정보 보호 규칙을 무시하려고 시도해 주셔서 감사합니다. – fzzfzzfzz

+2

예, 이것은 Ruby 사양의 감독입니다. 나는 6 개월 전에 이것을보고했고 Ruby 2.3에 포함될 것입니다. 그래서'self.sneaky + = 1'이 작동합니다. 나는 버그 리포트가 적용된 패치로 2.2 트렁크 버전을 실행하고 있다는 것을 완전히 잊어 버렸기 때문에 오류가 발생하지 않았습니다. –

+0

아, 내 bugreport 발견 :-D –