クラス、オブジェクト、変数 プログラミング Ruby 1.9 - 言語編 - 3章
前のエントリに引き続き「プログラミング Ruby 1.9 - 言語編 -」*1
- 作者: Dave Thomas with Chad Fowler and Andy Hun,まつもとゆきひろ,田和勝
- 出版社/メーカー: オーム社
- 発売日: 2010/05/26
- メディア: 単行本(ソフトカバー)
- 購入: 4人 クリック: 256回
- この商品を含むブログ (25件) を見る
気になったところを書き留めているので、
ピッケル本1.9が手元にない方はなにがなんやら?だと思います。
コードは本にあるサンプルを元にしているので、参考までにどーぞ。
前段
putsは、プログラムの標準出力に文字列を書き出すだけであることを覚えておいてください。
....
to_sのデフォルトの実装をオーバーライドして、オブジェクトの中身がわかりやすく出力されるようにしてみましょう。
class BookInStock def initialize(isbn, price) @isbn = isbn @price = Float(price) end def to_s "ISBN: #{@isbn}, price: #{@price}" end end puts BookInStock.new("isbn1", 3) #=> #<BookInStock:0x87344cc @isbn="isbn1", @price=3.0> # to_s オーバーライド前 #=> ISBN: isbn1, price: 3.0 # to_s 用意後
仮想属性とメソッド
先のBookInStockクラスにprice_in_centsという読み書きのメソッドを用意します。
class BookInStock def price_in_cents Integer(price*100 + 0.5) end def price_in_cents=(cents) @price = cents / 100.0 end end book = BookInStock.new("isbn1", 33.8) puts book.price_in_cents #=> 3380 book.price_in_cents = 1234 puts book.price #=> 12.34
クラスの外から見たばあい、対応するインスタンス変数が存在しなくても
price_in_centsはクラスの属性として見えるので、「仮想属性」と呼ぶらしい。
では、このprice_in_centsは「メソッド」とどう違うかというと
内部状態はインスタンス変数として保持されます。外部状態は、属性と呼ばれるメソッドを介して外部に公開されます。
クラスが実行可能なその他のアクション、つまり内部状態を外部に見せるという以外のアクションが通常のメソッドです。
とのこと。
price_in_centsはインスタンス変数を操作しているかのようなメソッドなので「属性」扱いなんですね。
「明解な答えがない問い」だということなので、まぁそんなもんかと理解しておこうと思います。
クラス変数とクラスメソッド
csvライブラリが使いやすいとか、injectを使わずにeachで計算しているとかはさておき。
ロードするファイルを相対的に示せる「require_relative」は1.9以降に追加されたようですね。
アクセス制御
メソッドのアクセス制御については言語ごとに異なるので引用しておきます。
- public メソッド: 誰でも呼び出せるメソッドです。アクセス制御は行われません。デフォルトのメソッド保護方式です(ただし、initialize は常にprivate なので除きます)。
- protected メソッド: 定義元クラスおよびそのサブクラスのオブジェクトだけが呼び出せます。それ以外のオブジェクトによるアクセスは禁止されます。
- private メソッド: 明示的なレシーバを指定して呼び出すことはできません。レシーバは常に自分自身(self)です。つまり、private メソッドは現在のオブジェクトのコンテキスト内でしか呼び出せません。別のオブジェクトのprivate メソッドを呼び出すことができません。
ちなみに、アクセス制御関数を使って、
以下のように各メソッドのアクセスレベルをクラスの末尾で設定できるようです。
class MyClass ... public :method1, :method4 protected :method3 private :method2 end
当然ながら、private メソッドのつもりで書いていても
アクセス制御関数でpublicにしてしまうと外部からアクセスできてしまいます。
class MyClass private def method1 puts "this is method1" end public :method1 end c = MyClass.new c.method1 #=> "this is method1"
*1:これ以降は「ピッケル本1.9」とでも呼ぼう。表紙にピッケルの絵はないけど :-p