sinatraのredirectとrailsのredirect_to

railsと違って、sinatraだとredirectメソッドを呼ぶとそれ以降が実行されない (って話をちらっとtwitterで見かけた)

get '/' do
  puts 'get sinatra index'
  redirect '/aaa'
  puts 'got index' # 呼ばれない
end

def index
  puts 'get rails index'
  redirect_to '/aaa'
  puts 'got index' # 呼ばれる
  render plain: 'hello' # エラー出る
end

どうやってるのかなと思ったらthrowしてた

def redirect(uri, *args)
  ...
  halt(*args)
end

def halt(*response)
  ...
  throw :halt, response
end

def invoke
  res = catch(:halt) { yield }
  ...
end

そんな感じの書き方いくつか

# raise-rescue
def hoge1
  puts '呼ばれる'
  stop1
  puts '呼ばれない'
end

def stop1
  raise :stop1
end

hoge1 rescue nil
# throw-catch sinatraはこれ
def hoge2
  puts '呼ばれる'
  stop2
  puts '呼ばれない'
end

def stop2; throw :stop2; end

catch(:stop2) { hoge2 }
# return
def hoge3
  puts '呼ばれる'
  stop3
  puts '呼ばれない'
end

def stop3; @return_from_lamba.call; end

lambda do
  @return_from_lamba = proc { return }
  hoge3
end.call
# Fiber.yield
def hoge4
  puts '呼ばれる'
  stop4
  puts '呼ばれない'
end

def stop4; Fiber.yield; end

Fiber.new { hoge4 }.resume

他にあるかな