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:ンな用途あるんか?って感じではありますが