Ruby Tips!

RubyのTipsを紹介します

forwardableとdelegateによるメソッドの移譲

forwardable

forwardableはクラスにメソッドの移譲を簡単に定義するためのライブラリだ。以下は配列へのメソッドの移譲により、独自のキューを実装する例である。def_delegatorメソッドにより、メソッドの移譲を定義する。

require 'forwardable'

class MyQueue
  extend Forwardable

  def initialize
    @q = []
  end

  def_delegator :@q, :push, :enq
  def_delegator :@q, :shift, :deq
  def_delegator :@q, :size
end

queue = MyQueue.new
queue.enq "a"
queue.enq "b"
p queue.size #=> 2
p queue.deq #=> "a"
p queue.deq #=> "b"

delegate

メソッドを個別に移譲するのではなく、すべてのメソッドを移譲したクラスを定義したい場合はdelegateライブラリが利用できる。

以下で定義するMyArrayは、Arrayにすべてのメソッドを移譲しており、配列と同様に扱うことができる。

require "delegate"

class MyArray < DelegateClass(Array)
  def initialize
    super []
  end
end

a = MyArray.new
a << 1
a << 2
a << 3
p a #=> [1, 2, 3]

実際にはこのクラスに独自のメソッドを追加したり、必要に応じて一部のメソッドを再定義して使用する。