フェーズハンドラの改良 †さて,経緯はいろいろあるのだが 現状のフェーズ遷移のハンドラの改良を行う. 現状では
これらは次のような場合に不便である.
これらを解決するために,3つのハンドラの追加様式を統合し,次のようにする.
つまり,例えば add_start_handler(:phase1, method) を指定すると,元のフェーズにかかわらず:phase1に遷移した時,methodが実行される. ここに, add_start_handler(:phase1, :phase2, method2) を追加すると,元のフェーズが:phase2で,:phase1に遷移した時,method2が実行され, それ以外のフェーズから:phase1に遷移したときはmethodが実行される. class Phase def add_handler(handler, args) case args.size when 2 phase, method = args handler[phase] = method when 3 # don't care of old/new phase phase1, phase2, method = args handler[[phase1,phase2]] = method else raise(ArgumentError, "wrong number of arguments (#{args.size} for 2 or 3)") end end def add_start_handler(*args) # phase, method # don't care of oldphase # phase, oldphase, method add_handler(@start_handler, args) end def add_end_handler(*args) # phase, method # don't care of nextphase # phase, nextphase, method add_handler(@end_handler, args) end def add_condition_handler(*args) # oldphase, method # don't care of nextphase # oldphase, nextphase, method add_handler(@trans_condition_handler, args) end def get_handler(handler, phase1, phase2) method = handler[[phase1, phase2]] method = handler[phase1] unless method return method end def trans_condition_check cond = get_handler(@trans_condition_handler, @phase, @next_phase) return if cond && !cond.call old = @phase @phase = @next_phase @next_phase = nil # start handler method = get_handler(@start_handler, @phase, old) method.call if method end def change(phase) # end handler method = get_handler(@end_handler, @phase, phase) method.call if method # set next_phase @next_phase = phase # trans condition check trans_condition_check unless wait? end end |