2009-11-07 14 views
162

@対自己がいくつかのコードです:インスタンス変数:ここ

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 

私が知りたいのは何がage_difference_with方法で@ageself.ageを使用しての違いです。

答えて

237

書く@ageは、インスタンス変数@ageに直接アクセスします。 self.ageを記述すると、オブジェクトにはageというメッセージが送信され、通常はインスタンス変数@ageが返されますが、特定のサブクラスに実装されている方法に応じて他の多くの処理を行うことができます。たとえば、実際には若い年齢であることを常に報告するMiddleAgedSocialiteクラスがあるとします。あるいは、PersistentPersonクラスは永続的なストアからそのデータを遅延読み込みし、すべての永続データをハッシュでキャッシュすることがあります。

+1

私は一度本をレールで読んだことがあり、この自己と@の違いを理解していないので、パブリックインターフェイスを使用して自分のデータを作るために自分のメソッド(setterとgetterではない)私はgetterとsetterで定義するのに時間を費やしました。 – sarunw

+0

...英語...どのような数のものが何を意味しますか?私は与えられた最後の2つの例を得ていませんでした。 – user2167582

21

違いは、メソッドの実装とメソッドの使用を分離していることです。プロパティの実装が変更された場合 - 生年月日を保持し、現在と誕生日の間の時間の差異に基づいて年齢を計算するなど - メソッドに応じたコードは変更する必要はありません。プロパティを直接使用した場合、変更はコードの他の領域に伝播する必要があります。この意味では、プロパティを直接使用することは、クラスが提供するインターフェイスを使用するよりも脆弱です。

+12

ああ、self.ageはインスタンス変数かインスタンスメソッドのどちらかを参照することができますか? –

2

違いはありません。私はそれがお互いの近くにself.ageother_person.ageを見ることのドキュメンタリーの価値のためだけに行われたと思う。

私は、実際のゲッターが将来書き込まれることを許していると思います。これはインスタンス変数を返すだけでなく、メソッドを変更する必要はありません。

しかし、オブジェクトの実装が変更された場合、オブジェクト自体の中の単純な参照が完全に合理的である点で、他のメソッドを変更するのが妥当であると心配する抽象化はありません。

いずれの場合でも、ageプロパティの抽象化では、ageもアクセサーを呼び出すため、selfの明示的な使用についてはまだ説明していません。

5

あなたが初期化子を削除すると初期化子を生成するためのきちんとした方法であるStruct.newからクラス(How to generate initializer in 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 

を返します継承したときに注意して返されます

クラス定義

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 
-3

@ageを返します - インスタンス変数の年齢

self.ageは間違いである - インスタンスプロパティの年齢を指します。

-1

最初の回答は全く正しいですが、相対的な初心者としては、それが暗示していることをすぐにわかりませんでした(自分にメッセージを送信するのはどうでしょうか...)。私は簡単な例が助けになると思う:

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 
+2

この例では、状況がより混乱しました。 –

+0

申し訳ありませんが、この例ではコメントが足りません。私はあなたの推論に従うことができません。 – kouty

関連する問題