実用性はない(と思う)ネタ系ライブラリ。ぼちぼち追加予定。
ソース: dispatch.rb
引数型によるメソッドオーバロードができるようにするライブラリ。Rubyの文法を最大限に悪用した、奇怪な構文が特徴。
def hoge(*args) dispatch(args). when(Integer) do |i| printf("Integer %d\n", i) end. when(String) do |s| printf("String %s\n", s) end. when(String, Integer) do |s, i| printf("String %s and Integer %d\n", s, i) end. end end hoge(3) hoge("s") hoge("t", 4)
StrongTypingがもっとまっとうな構文で同じ事を実現してるので、使うならこちらをお勧めします(笑)。
ソース: product.rb
クラスの組(product)に対してメソッドを定義できるようにするライブラリ。
例えば以下では、AcidクラスとBaseクラスの組に対して、saltというメソッドを定義しています。
class Acid include(Producable) attr_accessor(:anion) end class Base include(Producable) attr_accessor(:cation) end def_product(Acid*Base) do def salt return rhs.cation + lhs.anion end end
使うときはこんな感じ。
h_cl= Acid.new() h_cl.anion= "Cl" na_oh= Base.new() na_oh.cation= "Na" p (h_cl*na_oh).salt # => "NaCl" p (h_cl*na_oh).class # => Acid*Base
一応、元のクラスの継承関係も反映されます。
class WeakBase < Base end def_product(Acid*WeakBase) do def acid? return true end end nh4_oh= WeakBase.new() nh4_oh.cation= "NH4" p (h_cl*nh4_oh).salt # => "NH4Cl" p (h_cl*nh4_oh).acid? # => true p (h_cl*nh4_oh).is_a?(Acid*Base) # => true
ただ、この継承には色々制限が有って、例えば、Acid*Baseより前にAcid*WeakBaseを定義してしまうと、変になります。あと、Rubyでは多重継承ができないので、基底クラス候補が複数いるような状況では、それらに共通の基底クラスが、基底クラスになります(わけわからん)。
もちろん、Arrayなどの既存のクラスのproductも定義できます。ただ、*演算子だと衝突するので、もうちょっと穏健な(?)productという関数も用意しました。
def_product(Array*Array) do def map(&block) return (0...lhs.size).map(){ |i| yield(lhs[i], rhs[i]) } end end p product([1, 2], [3, 4]).map(){ |a, b| a+b } # => [4, 6]
3個以上のproductは、「productのproduct」として定義できます。
def_product(Object*Symbol*Array) do def call() obj= lhs.lhs sym= lhs.rhs ary= rhs obj.send(sym, *ary) end end p product("hoge", :gsub, [/o/, "e"]).call() # => "hege"
O/Rマッパみたいなものを考えてて、複数テーブルに紐づくテーブルってオブジェクトではどう書くんだろうと思って、思いついたもの。