[ruby] 인스턴스 변수 : self vs @

다음은 몇 가지 코드입니다.

class Person
  def initialize(age)
    @age = age
  end

  def age
    @age
  end

  def age_difference_with(other_person)
    (self.age - other_person.age).abs
  end

  protected :age
end

내가 알고 싶은 것은 사용 사이의 차이 @ageself.ageage_difference_with방법.



답변

쓰면 @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접근자를 호출 했기 때문에 의 명시 적 사용을 설명하지 않습니다 .


답변

@age-확실히 인스턴스 변수 연령입니다

self.age-인스턴스 속성 연령을 나타냅니다.


답변