Ruby 標準ライブラリの tempfile.rb をのぞいたら、require 'delegate' となって、delegate (委譲) が使われていた。
Ruby リファレンスマニュアルの説明では メソッドの委譲(delegation)を行う。 何回読んでもさっぱりわからないので今まで敬遠していたが、サンプルとしてベクトルの計算をするプログラムを作ってみたら何となくわかったような気がした。 まず、ベクトルは Array クラスを利用すれば配列として表すことができる。しかし配列の足し算をすると、[1,2] + [3,4] = [1, 2, 3, 4] となってベクトルの計算はできない。 それならということで、ベクトル専用のクラスを作ってもいいが、a[1] のようなものもメソッドで定義しなくてはいけなくなる。 そこで、delegate (委譲)を利用して Array クラスのメソッドを Vector クラスのオブジェクトで使えるようにすればずいぶん手抜きができる。delegate は Delegator クラスを継承する方法、SimpleDelegator を使う方法、DelegateClass() 関数を使う方法の3つがあるが、そのうちの DelegateClass() 関数を使う方法を試してみた。 DelegateClass() を使ってVectorクラスのオブジェクトをArrayクラスに移譲するには、次のようにする。 class Vector < DelegateClass(Array) つまり定数 Array を DelegateClass() 関数の引数にして呼び出すと、Arrayクラスに移譲するためのクラスができる。そこで、そのクラスから継承させて Vector クラスを作ると、Vector クラスのオブジェクトはすべてArrayクラスのメソッドが使えてしまうというわけだ。 実は次のように、DelegateClass(Array) を継承するだけで、Vectorクラスのオブジェクトを作ることができてしまう。 C:\Users\******\Ruby>irb irb(main):001:0> require 'delegate' => true irb(main):002:0> class Vector < DelegateClass(Array) irb(main):003:1> end => nil irb(main):004:0> a = Vector.new([1,2]) => [1, 2] irb(main):005:0> a[0] => 1 しかし、a = Vector.new のように引数なしの使い方もしたいし、initialize メソッドを定義してみた。 def initialize(obj = []) super(obj) end iniitalize メソッドの引数を上位クラスに渡すだけだから楽なものだ。 つぎに、ベクトルの加算を定義した。 def +(other) result = Vector.new for i in 0...self.size result << self[i] + other[i] end result end たったこれだけのプログラムで、ベクトルの足し算ができるようになった。今までのプログラムを、vector.rb という名前で保存した。 ファイル名: vector.rb require 'delegate' class Vector < DelegateClass(Array) def initialize(obj=[]) super(obj) end def +(other) result = Vector.new for i in 0...self.size result << self[i] + other[i] end result end end irb で実行してみた。 irb(main):001:0> require 'vector' => true irb(main):002:0> a = Vector.new([1,2]) => [1, 2] irb(main):003:0> b = Vector.new([3,4]) => [3, 4] irb(main):004:0> a + b => [4, 6] 自分でメソッドを定義しなくても委譲しさえすれば、すぐに自作のクラスのオブジェクトを操作できるようになるのだから便利なものだ。わけのわからなかった delegate (委譲)だが、ずいぶん便利な道具だったのだ。
by tnomura9
| 2008-11-20 19:14
| Ruby
|
Comments(0)
|
カテゴリ
新型コロナウイルス 主インデックス Haskell 記事リスト 圏論記事リスト 考えるということのリスト 考えるということ ラッセルのパラドックス Haskell Prelude Ocaml ボーカロイド 圏論 jQuery デモ HTML Python ツールボックス XAMPP Ruby ubuntu WordPress 脳の話 話のネタ リンク 幸福論 キリスト教 心の話 メモ 電子カルテ Dojo JavaScript C# NetWalker ed と sed HTML Raspberry Pi C 言語 命題論理 以前の記事
最新のトラックバック
最新のコメント
ファン
記事ランキング
ブログジャンル
画像一覧
|
ファン申請 |
||