2

Sinatra アプリを DRY する方法を探していて、いくつかのスコーピングの問題に遭遇しました。特に、ヘルパーと Sinatra 関数がハンドラー内で利用できません。このコードを修正する方法があれば教えてください。さらに重要なことに、何が起こっているのでしょうか?

ありがとうございました。

require 'sinatra'
require 'pp'

helpers do
  def h(txt)
    "<h1>#{txt}</h1>"
  end
end

before do
  puts request.path
end


def r(url, get_handler, post_handler = nil)
  get(url){ get_handler.call } if get_handler
  post(url){ post_handler.call } if post_handler
end


routes_composite_hash = {
    '/' => lambda{ h('index page'); pp params }, #can't access h nor params!!!
    '/login' => [lambda{'login page'}, lambda{'login processing'}],
    '/postonly' => [nil, lambda{'postonly processing'}],
}

routes_composite_hash.each_pair do |k,v|
  r(k, *v)
end
4

2 に答える 2

1

ブロック内で定義するメソッドは、helpers do .. endルート、フィルター、およびビュー コンテキスト内でのみ使用できます。したがって、それらの内部で使用していないため、機能しません。ラムダは実行コンテキストを保持します。つまり、ハッシュ{'/' => lambda { h }..}ではコンテキストが存在しますがmain、メソッド内getではコンテキストが変更され、ヘルパーはこのコンテキストでのみ使用できます。

ただし、やりたいことを達成するには (これを避けることをお勧めしますが)、ヘルパーをアプリ ファイル自体の中でラムダとして定義するだけです。あなたの場合、それは次のようになります。

def h(txt) 
  "<h1>#{txt}</h1>"
end

# And then the rest of the methods and the routes hash

このように、hメソッドはmainオブジェクトのコンテキスト内にあるため、全体的に表示されます。

于 2013-08-09T19:49:04.467 に答える