답변:
쓰면 @age
인스턴스 변수에 직접 액세스합니다 @age
. 쓰기 self.age
는 객체에게 메시지를 보내도록 지시하는데 age
, 보통 인스턴스 변수를 반환 @age
하지만 age
주어진 서브 클래스에서 메소드가 구현되는 방식 에 따라 다른 많은 작업을 수행 할 수 있습니다. 예를 들어 MiddleAgedSocialite 클래스를 사용하여 실제보다 나이가 10 세 미만임을 항상보고 할 수 있습니다. 또는 실제로는 PersistentPerson 클래스가 영구 저장소에서 해당 데이터를 느리게 읽고 모든 영구 데이터를 해시로 캐시 할 수 있습니다.
차이점은 메소드 사용과 메소드 사용을 분리한다는 것입니다. 속성의 구현이 변경되는 경우 (생년월일을 유지 한 다음 현재 시간과 생년월일의 차이를 기준으로 연령을 계산하는 경우) 분석법에 따른 코드를 변경할 필요가 없습니다. 이 속성을 직접 사용한 경우 코드의 다른 영역으로 변경 내용을 전파해야합니다. 이런 점에서 클래스에서 제공하는 인터페이스를 사용하는 것보다 속성을 직접 사용하는 것이 더 취약합니다.
Struct.new
초기화 프로그램을 생성하는 깔끔한 방법 인 클래스를 상속 할 때 경고하십시오 ( Ruby에서 초기화 프로그램을 생성하는 방법? )
class Node < Struct.new(:value)
def initialize(value)
@value = value
end
def show()
p @value
p self.value # or `p value`
end
end
n = Node.new(30)
n.show()
돌아올 것이다
30
nil
그러나 이니셜 라이저를 제거하면
nil
30
클래스 정의
class Node2
attr_accessor :value
def initialize(value)
@value = value
end
def show()
p @value
p self.value
end
end
생성자를 제공해야합니다.
n2 = Node2.new(30)
n2.show()
돌아올 것이다
30
30
첫 번째 대답은 전적으로 정확하지만 친숙한 초보자로서 그것이 의미하는 바를 즉시 알지 못했습니다 (메시지를 자신에게 보내는가? 어 ....). 짧은 예가 도움이 될 것이라고 생각합니다.
class CrazyAccessors
def bar=(val)
@bar = val - 20 # sets @bar to (input - 20)
end
def bar
@bar
end
def baz=(value)
self.bar = value # goes through `bar=` method, so @bar = (50 - 20)
end
def quux=(value)
@bar = value # sets @bar directly to 50
end
end
obj = CrazyAccessors.new
obj.baz = 50
obj.bar # => 30
obj.quux = 50
obj.bar # => 50
차이가 없습니다. 나는 그것이 단지 보는 다큐멘터리 값에 대해 수행 된 것으로 의심 self.age
하고 other_person.age
서로 가까이.
나중에 사용하면 실제 getter를 작성할 수 있으며 인스턴스 변수를 반환하는 것보다 복잡한 작업을 수행 할 수 있다고 생각합니다.이 경우 메서드를 변경할 필요가 없습니다.
그러나 객체의 구현이 변경된 경우 다른 메소드를 변경하는 것이 합리적이라고 생각할 가능성은 거의 없습니다.
어쨌든 age
속성의 추상화는 여전히 self
일반 적으로 age
접근자를 호출 했기 때문에 의 명시 적 사용을 설명하지 않습니다 .