Sinatra,DRY和范围

时间:2013-08-09 14:45:10

标签: ruby sinatra

我正在寻找干燥我的Sinatra应用程序并遇到一些范围问题的方法 - 特别是我的处理程序中没有帮助程序和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

2 个答案:

答案 0 :(得分:2)

有趣!

这样做:

def r(url, get_handler, post_handler = nil) 
  get(url, &get_handler) if get_handler
  post(url, &post_handler) if post_handler
end


routes_composite_hash = {
    '/' => lambda{ h('index page'); pp 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

正如Kashyap所解释的那样,您在main上下文中调用了get和post处理程序。这只是将发送的lambda转换为块并将其传递给所需的方法。

答案 1 :(得分:1)

您在helpers do .. end块中定义的方法仅在路由和过滤器以及视图上下文中可用,因此,由于您未在其中任何一个中使用它们,因此它将无法工作。 Lambdas保留执行上下文,这意味着在哈希{'/' => lambda { h }..}中,上下文为main但在get方法内,上下文发生变化,助手只在此上下文中可用。

要实现您想要做的事情,(尽管我建议您不要这样做),您可以在应用程序文件本身内将帮助程序定义为lambdas。在你的情况下,它将是:

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

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

这样,h方法位于main对象的上下文中,因此将全部可见。