実用性はない(と思う)ネタ系ライブラリ。ぼちぼち追加予定。
ソース: 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マッパみたいなものを考えてて、複数テーブルに紐づくテーブルってオブジェクトではどう書くんだろうと思って、思いついたもの。