답변:
다른 접근자를 사용하여 코드를 읽는 사람에게 의도를 알리고 공용 API 호출 방법에 관계없이 올바르게 작동하는 클래스를 더 쉽게 작성할 수 있습니다.
class Person
attr_accessor :age
...
end
여기서 나는 나이를 읽고 쓸 수 있음을 알 수 있습니다.
class Person
attr_reader :age
...
end
여기에서는 나이 만 읽을 수 있음을 알 수 있습니다. 이 클래스의 생성자에 의해 설정되고 그 후에도 일정하다고 가정하십시오. 연령에 대한 뮤 테이터 (작성자)가 있고 해당 나이가 설정된 후에 변경되지 않는다고 가정하여 클래스를 작성한 경우 해당 뮤 테이터를 호출하는 코드에서 버그가 발생할 수 있습니다.
그러나 무대 뒤에서 무슨 일이 일어나고 있습니까?
당신이 쓰는 경우 :
attr_writer :age
그것은 다음과 같이 번역됩니다.
def age=(value)
@age = value
end
당신이 쓰는 경우 :
attr_reader :age
그것은 다음과 같이 번역됩니다.
def age
@age
end
당신이 쓰는 경우 :
attr_accessor :age
그것은 다음과 같이 번역됩니다.
def age=(value)
@age = value
end
def age
@age
end
그것을 아는 것은 여기에 다른 생각이 있습니다. attr _... 도우미가없고 접근자를 직접 작성해야한다면 클래스에 필요한 것보다 더 많은 접근자를 작성 하시겠습니까? 예를 들어, 나이 만 읽을 필요가 있다면, 그것을 쓸 수있는 방법을 쓰시겠습니까?
attr_reader
정의 된 accesor는 수동으로 정의 된 접근자가 수행하는 시간의 86 %가 걸립니다. Ruby 1.9.0의 경우, attr_reader
정의 된 접근자는 수동으로 정의 된 접근자가 수행하는 시간의 94 %를 걸립니다. 그러나 모든 테스트에서 접근자는 빠릅니다. 접근자는 약 820 나노초 (Ruby 1.8.7) 또는 440 나노초 (Ruby 1.9)가 걸립니다. 이러한 속도에서 attr_accessor
전체 런타임을 1 초까지 향상시킬 수있는 성능 이점을 얻으려면 접근자를 수억 번 호출해야합니다 .
attr_accessor :a, :b
접근자는 변수가 아닌 컨텐츠에 대한 액세스를 제한한다는 것을 이해하는 것이 중요합니다. 루비에서 다른 OO 언어와 마찬가지로 모든 변수는 인스턴스에 대한 포인터입니다. 예를 들어, 해시에 대한 속성이 있고이를 "읽기 전용"으로 설정하면 항상 내용을 변경할 수 있지만 포인터 내용은 변경할 수 없습니다. 이것 좀봐:
irb(main):024:0> class A
irb(main):025:1> attr_reader :a
irb(main):026:1> def initialize
irb(main):027:2> @a = {a:1, b:2}
irb(main):028:2> end
irb(main):029:1> end
=> :initialize
irb(main):030:0> a = A.new
=> #<A:0x007ffc5a10fe88 @a={:a=>1, :b=>2}>
irb(main):031:0> a.a
=> {:a=>1, :b=>2}
irb(main):032:0> a.a.delete(:b)
=> 2
irb(main):033:0> a.a
=> {:a=>1}
irb(main):034:0> a.a = {}
NoMethodError: undefined method `a=' for #<A:0x007ffc5a10fe88 @a={:a=>1}>
from (irb):34
from /usr/local/bin/irb:11:in `<main>'
보시다시피 Hash @a에서 키 / 값 쌍을 삭제하고 새 키를 추가하고 값을 변경하십시오. 그러나 읽기 전용 인스턴스 변수이므로 새 객체를 가리킬 수 없습니다.