メモ書き程度でしかないけど。
RockMotive 1.0.0.beta1 をついさっきリリースした。大体理想とする機能の実装が終わったので一旦 beta という形で公開するに至った。まだドキュメント等はない。
クラス名の変更
先日の記事を書いた時点では RM::Interaction
だったものが RM::Context
に変更になった。素直に DCI に名前を寄せた形になる。特に抵抗のある事柄ではなかったので問題ない。
RM::Interaction
から RM::Context
に変わったことで .interact
から .execute
にメソッド名も変わってる。これも特にこだわりがあったものではないので、巷の DCI 実装に名前を寄せた形。
#execute
内のロジックの変更
メタプログラミング度は上昇していて、 #execute
内での extend はインライン展開されるようになった。意味がわからないと思うのでこう変わったよというコード例を載せておく。
# 元の実装
args.each_with_index do |arg, n|
role = roles[n]
arg.exnted(role) if role
end
# 新しい実装
eval(<<-EOF)
#{roles.each_with_index { |role, n| role.nil? ? '' : "args[#{n}].extend(#{role.name})"}
EOF
気持ち悪いことしてんなぁと思ったら正常。より高速にする方法を模索していて Array#each
のコストを削れないかと考えた結果、どの引数にどのロールを当てるのかは固定なのだから事前に展開可能だということでこの形に至った。ちなみにほとんど誤差の範囲であったということも書いておく。あまりにも厳しいコードなので元の形に戻るかもしれない。
キーワード引数への対応
推奨する利用法としてキーワード引数を推していきたいという気持ちがある。なんでかっていうと、先日の例に出てくる
def execute(shopper, seller)
こういうコードは、引数の名前にこそ意味があって、引数の順序に意味があるわけではない、というのが肝要な点の為。また、呼び出し元のコードでは DealContext.execute(current_user, seller_user)
などのような形になることが想像できるが、この時、どういったロールが与えられるのか、呼び出し元では想像がつかず混乱を招くことを考えた結果。
キーワード引数に対応した現在では、上記のコードは
def execute(shopper:, seller:)
と書くことができるようになり、また呼び出し元では
DealContext.execute(seller: seller_user, shopper: current_user)
のように書くことができるようになる。引数の順序に意味はなく、与えられる名前こそに意味があるという点でこの表記に収まることが気に入っている。
以上。この辺でそろそろ引き上げて DCI 熱を一回冷まさないと……