Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

Ruby標準モジュール"Forwardable"でコアクラスのオレオレ式改造をしてみる

Ruby標準モジュール"Forwardable"をつかうと、
移譲というテクニックが使えるようになります。
これを生かすと元あるコアクラスをオレオレ式に拡張して扱う事ができるわけです。

実際のところ

  • Stringを土台とする
  • String#upcase、String#nextは流用
  • String#downcaseはString#upcaseで代用*1

これをforwardableで実現すると、次のようなスクリプトになります。

require 'forwardable'

class MyString
  extend Forwardable
  attr_reader :str
  def initialize(init = "")
    @str = init
  end

  def_delegators :@str, :next,   :upcase
  def_delegator  :@str, :upcase, :downcase
end

q = MyString.new("po")
p q.next
p q.upcase
p q.downcase
p q + "hoge"

これの実行結果は以下の通り

"pp"
"PO"
"PO"
forwardable.rb:19:in `<main>': undefined method `+' for #<MyString:0x007fd8fa0ea2b0 @str="po"> (NoMethodError)

移譲したメソッドは実行可能、上書きされたメソッドも意図通り。
さらに、移譲してないメソッドは使えません。
Effective Rubyによると、下手にコアクラスを継承するより移譲の方がいいそうです。

参考もと

*1:ンな用途あるんか?って感じではありますが