Blockはクロージャを期待する場合と, 単なるblockスタイルで分かりやすく手続きを書きたいという2つの期待があると思ってる。(両方期待する場合もある)

1 get '/' do
2   "Hello Sinatra"
3 end

今日はSinatraようにblockスタイルで分かりやすく手続きを書きたい場合について書いていく。 大凡このような場合、blockを宣言したクラスはプロキシの責務を負うようなクラスで、実際blockを処理するのはサービス層に分類される別クラスだったりする。実現方法としてまず思いつくのはinstance_eval

 1 class Iga
 2   def kuchiyose &block
 3     Dragon.new("DragonFire").nin &block
 4   end
 5 end
 6 
 7 class Dragon
 8   attr_reader :waza
 9 
10   def initialize(waza)
11     @waza = waza
12   end
13 
14   def nin &block
15     instance_eval(&block)
16   end
17 end
1 Iga.new.kuchiyose do
2   "Ninpo: #{waza}" # => "Ninpo: DragonFire"
3 end

Iga忍者は口寄せの術を使い、龍を召喚しドラゴンフレイムの攻撃に成功している。口寄せなのでIgaクラスがドラゴンフレイムの保持はしておらず、Dragonクラスが保持する。 ポイントはIgaクラスのインスタンスで束縛されているblockがinstace_evalによってDragonクラスの環境で実行できている事だ。
こういうTipsを有名なライブラリは当たり前のように使っているが、なんせ名前付けされてないので読めはするものの、書くとなるとなかなか思いつかなかったりする。アプリケーションエンジニアとはこういうTipsを積み重ね自在にコードを操るスキルも必要だと思う。インフラエンジニアも巷で話題のフルスタックエンジニアもコードは書けるのだし。




comments powered by Disqus


© 2015 kyuden