Created
August 7, 2013 16:08
-
-
Save shinokaro/6175501 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Script < Fiber | |
def self.new(*dsl_mods, &block) | |
Class.new(self).tap do |c| | |
# DSLメソッド郡をextendする、DSLを組み合わせ可能にしている | |
dsl_mods.each{ |mod| extend(mod) } | |
# 生成したクラスではnewメソッドでインスタンスを生成するように書き換える | |
c.class_eval do | |
def self.new(*args, &block) | |
self.allocate.__send__(:initialize, *args, &block) | |
end | |
end | |
# 生成したクラスのスコープでブロックを実行する。インスタンスメソッドのセットアップなどを想定 | |
# 与えるブロック内でincludeを行えば良い | |
c.class_eval(&block) if block_given? | |
end | |
end | |
def initialize(*args, &block) | |
# スクリプトはFiberとして動作してほしいため、superでFiber化する | |
# resumeされた時に無名クラスを生成する、このとき自身を継承することによって | |
# スクリプト実行環境であるクラスメソッドとFiberインスタンスに干渉するための | |
# インスタンスメソッドを引き継がせる | |
# Fiberの特性上、resumeされるまでブロック内部は実行されないが、 | |
# 引き数argsとblocKはこの時点で束縛される。 | |
# argsを必要としたのはスクリプトファイルを読み込んで与える場合を想定したため。 | |
# 無名モジュールに書き換えても良い。違いを利用するには追加コードが必要。 | |
super(){ | |
Class.new(self.class).class_eval(*args, &block) | |
} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment