7/19 OoO 第三回 : EGSR08 祭り
イベントのお知らせです。
EGSR 2008の採択論文が出揃ってきたのを受けて、
OoO(=オフラインレンダラ野郎のためのオフラインレンダラについて議論するオフライン会)の第三回が開催されます。
オフラインレンダラ野朗の皆様は奮ってご参加ください。
イベントのお知らせです。
EGSR 2008の採択論文が出揃ってきたのを受けて、
OoO(=オフラインレンダラ野郎のためのオフラインレンダラについて議論するオフライン会)の第三回が開催されます。
オフラインレンダラ野朗の皆様は奮ってご参加ください。
Kagemushaを使って、スコープを汚さないDSLスタイルのinitialize
メソッドを提供する方法を紹介します。
ruby>>
require 'rubygems'
require 'kagemusha'
class Foo
def initialize(&block)
bar = nil # default value
meta = eval('class << self; self end', block.binding)
Kagemusha.new(meta) do |kage|
kage.def(:bar){|bar|} # substitution
end.swap(&block)
@bar = bar
end
end
def bar(x); puts x end
foo = Foo.new do
bar 'bar'
end
puts foo.inspect # => #<Foo:0xb7c03de0 @bar="bar">
bar "hello!" # => hello!
<<--
bindingのコンテクストからメタクラスを取得し、
Kagemushaを使って限定的にbarメソッドを置き換えています。Foo.newのブロック内から抜けると、barの呼び出しはグローバルスコープのbarを呼んで、
"hello!"が出力されます。
この方法は、initialize以外にも、
ブロックを受けるインスタンスメソッド全般に利用できます。
例えば、以下のようなコードで、一時変数t
の存在が気になる場合などですね。
rails>>
create_table do |t|
t.string :foo
end
<<--