回答:
書き込み@age
はインスタンス変数に直接アクセスします@age
。書き込みself.age
は、オブジェクトにそれ自体にメッセージを送信するように指示しますage
。これは通常、インスタンス変数を返します@age
が、age
メソッドが特定のサブクラスでどのように実装されているかに応じて、他の多くのことを実行できます。たとえば、実際の年齢よりも10歳若い年齢を常に報告するMiddleAgedSocialiteクラスがあるとします。または、より実際的には、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
近くで見るというドキュメンタリーの価値のためだけに行われたのではないでしょうか。
将来的に実際のゲッターを使用できるようになると思います。インスタンス変数を返すだけではなく、もっと複雑なことを行う可能性があります。その場合、メソッドを変更する必要はありません。
しかし、これは、オブジェクトの実装が変更された場合に他のメソッドを変更することが合理的であると考えると、ありそうもない抽象化です。ある時点で、オブジェクト自体内の単純な参照が完全に合理的です。
いずれの場合age
でもself
、プレーンage
のアクセサも呼び出されたため、プロパティの抽象化はの明示的な使用を説明していません。
@age-間違いなくインスタンス変数の年齢
self.age-インスタンスプロパティの年齢を指します。