2011-11-03 13 views
5

을 사용하는 경우 문자열 변수를 수정할 수있게합니다. 이상한 행동으로 다른 사람이 내가 본 것을 확인할 수 있는지 궁금해합니다.Ruby attr_reader는 <<

멤버 변수를 사용하여 클래스를 만들고 attr_reader로 읽을 수 있도록한다고 가정합니다. 다음과 같은 처리를 할 때

class TestClass 
    attr_reader :val 

    def initialize(value) 
    @val = value 
    end 
end 

지금, 내가 단지 그것을 읽기 권한 부여에도 불구하고, @val의 값을 수정할 것으로 보인다.

test = TestClass.new('hello') 
puts test.val 
test.val << ' world' 
puts test.val 

이이 항상 사실이

+0

'attr_reader'는 값을 설정할 수 없다는 것을 의미합니다. 즉,'value ='메소드가 정의되어 있지 않습니다. 확실히 당신이 객체에 대한 메서드를 호출 할 수 없다는 것을 의미하지는 않습니다. –

답변

4

당신은 정말 발 속성을 작성하지 않는 경우이 내가 IRB 그렇게 확신하지에서했던 몇 가지 테스트에서 불과 결과

hello 
hello world 

반환합니다. 당신은 그것을 읽고 그것에 대한 메소드를 호출합니다 ('< <'메소드).

당신이 설명하는 수정의 종류를 막는 액세서를 원한다면, attr_reader를 사용하는 대신 @val의 복사본을 반환하는 메소드를 구현하는 것이 좋습니다. 귀하의 예제의

2

그냥 약간의 수정 :

test = TestClass.new([]) 

지금 당신이 얻을 (내부보기를 얻기 위해 페이지에 둔다 교체)해야합니다

[] 
['hello'] 

그것은 같은 일입니다. 너는 '발레'를 읽고, 이제 너는 그걸로 무언가를 할 수있다. 예제에서는 Array에 무언가를 추가하고, 예제에서는 String에 무언가를 추가합니다.

읽기 액세스는 수정할 수있는 개체를 읽고 쓰기 액세스는 특성을 바꾸고 바꿉니다.

은 아마 당신은 freeze을 찾습니다이 예기치는,이 정확히 맞아 보이지만

__temp.rb:12:in `<main>': can't modify frozen string (RuntimeError) 
hello 
0

:이 끝나는

class TestClass 
    attr_reader :val 

    def initialize(value) 
    @val = value 
    @val.freeze 
    end 
end 

test = TestClass.new('hello') 
puts test.val 
test.val << ' world' 
puts test.val 

. 설명하겠습니다.

attr_readerattr_writer 클래스 매크로 메서드는 인스턴스 변수에 대해 "getter"및 "setter"메서드를 정의합니다.

"getter"메서드가 없으면 단순히 해당 개체의 컨텍스트에 있지 않기 때문에 개체의 인스턴스 변수에 액세스 할 수 없습니다. 은 "세터"방법은 기본적으로 이것이다 : 당신이 "수"를하고 조작하는 경우 방법 자체의 세트로 변경 가능한 객체에 대한 인스턴스 변수가 가리키는 이후

def variable=(value) 
    @variable = value 
end 

, 그것은 추론하기 위하여 서있다가 이러한 변경 것 갖다. 위의 setter 메서드를 사용하여 variable.<<(value)을 호출 할 필요가 없습니다.

관련 문제