2011-01-31 2 views
0

私はPragmatic Bookselfの "Programming Ruby 1.9 (3rd Edition)"を使い始めました。私はちょっとした説明が必要なコードを見つけました。Rubyを使って仮想属性のインスタンス変数を呼び出す

書籍を所有している場合は、第3章の「クラス、オブジェクト、変数」、特に仮想属性に関するセクションを参照してください。

基本的に、いくつかのインスタンス変数を設定するイニシャライザでクラスを定義します。そのうちの1つは@priceです。この変数は、そのようなattr_accessorで作成したアクセサ/ミューテータを持っています

attr_accessor :price 

、単にこの行から値を返すと呼ばれる仮想属性、price_in_centsを持っていることをクラス:

Integer(price*100 + 0.5) 

今、私の質問をされますなぜ仮想属性内のprice@という接頭辞が付きませんか?これは明らかにインスタンス変数を扱っています。 @を使わないでコードを実行すると、と同じように動作します。何故ですか?

P.S.申し訳ありませんがコードを卸売するだけではなく、これは本のコードに関する質問であるため、私はどのような法的権利を掲示しなければならないのかよく分かりませんでした。

答えて

3

これは、受信者なしのメッセージ送信です。

ルビーでは、受信者selfが暗黙的です。あなたが望むなら、それを省略することができます。したがって、priceは、基本的にself.price(アクセス制限を無視した場合)と同じです。

つまり、attr_accessorで定義したメソッドpriceを呼び出しています。

+0

これは、単に 'price'を返すだけではない場合に備えて、' price'変数がアクセサを提供するクラスを通してアクセスされるようにするためです。 –

+1

@ Jean-Charles:そうです。基本的にはオブジェクト指向の基本原理です。*すべてがメッセージ送信*です。変数へのアクセスは、メッセージ送信ではなく、オブジェクト指向ではないため、可能ならば避けるべきです。これはあなたの*表現の独立性を買います*:price_in_centsメソッドは、価格を表現する方法を完全に知らないので、コードを変更せずに表現を変更することができます(インスタンス変数の代わりにdatabseseから引き出すなど)。 –

0

あなたは簡単にその2つの参照(price@price)が同じオブジェクトを指していることを確認することができます。

#!/usr/bin/env ruby 

class MyPrice < Object 
    attr_accessor :price 

    def initialize(price = 0) 
    @price = price 
    end 

    def price_in_cents 
    Integer(price * 100 + 0.5) 
    end 

    def objects 
    puts "@price.object_id: #{@price.object_id}" 
    puts "price.object_id: #{price.object_id}" 
    end 
end 

p = MyPrice.new(150) 
p.objects 
puts "price in cents: #{p.price_in_cents}" 

生成する:

# ./price.rb 
@price.object_id: 301 
price.object_id: 301 
price in cents: 15000 

price@priceの両方がオブジェクトを持っているという事実を301のidは、それらが両方とも単一のオブジェクトへの参照であることを示しています。

+0

'price' *はオブジェクトへの参照ではなく、メッセージ送信です。 –

0

この質問は何年か前に掲載されましたが、誰かが上の例のような同様の問題に遭遇している場合に備えてです。

私はself.priceがattr_accessorと何の関係もないと考えていますが、self.priceはattr_accessorがインスタンス変数のショートカットになるクラスにのみ適用されます。 attr_accessorの前に '@'を入力する必要はありません。なぜなら、Javaに精通していれば、setterとgetterのショートカットとして機能するからです。 Rubyの簡単な方法の一部は、より雄弁に速く実行されます。

関連する問題