Kagemushaを使って、スコープを汚さないDSLスタイルのinitialize メソッドを提供する方法を紹介します。

   1  require 'rubygems'
   2  require 'kagemusha'
   3  
   4  class Foo
   5    def initialize(&block)
   6      bar = nil # default value
   7      meta = eval('class << self; self end', block.binding)
   8      Kagemusha.new(meta) do |kage|
   9        kage.def(:bar){|bar|} # substitution
  10      end.swap(&block)
  11      @bar = bar
  12    end
  13  end
  14  
  15  def bar(x); puts x end
  16  
  17  foo = Foo.new do
  18    bar 'bar'
  19  end
  20  
  21  puts foo.inspect # => #<Foo:0xb7c03de0 @bar="bar">
  22  bar "hello!"     # => hello!

bindingのコンテクストからメタクラスを取得し、 Kagemushaを使って限定的にbarメソッドを置き換えています。 Foo.newのブロック内から抜けると、 barの呼び出しはグローバルスコープのbarを呼んで、 "hello!"が出力されます。

この方法は、initialize以外にも、 ブロックを受けるインスタンスメソッド全般に利用できます。 例えば、以下のようなコードで、一時変数t の存在が気になる場合などですね。

   1  create_table do |t|
   2    t.string :foo
   3  end

posted by Png genki on Thu 17 Jul 2008 at 19:38 with 1 comment
Contents
KagemushaでCleanなDSLスタイルのinitializeを作る
Comments
dsjf: https://gist.github.com/6bf1bf2c3cbb5eb6e7a7 これ... '13-1
瀧内元気: おお、チェックしてみます。thx! '11-12
overisland: Reeder for iPhone もこの UI を実装していますね。 '11-12
瀧内元気: その情報は見たのですが、以下のサイトによると、現在はまた必要になってるっぽいんですよね。 ... '11-12
tkawa: http://devcenter.heroku.com/articles/rails31_he... '11-12
Services from s21g
twpro(ツイプロ)
Twitterプロフィールを快適検索
地価2009
土地の値段を調べてみよう
MyRestaurant
自分だけのレストラン手帳
Formula
ブログに数式を埋め込める数式コミュニティ