Sinatra允许return values of route blocks采用多种不同形式。
Sinatra如何知道如何从每种类型的返回值中提取status
,headers
和body
?
特别是,我正在寻找执行此操作的源代码(逻辑),因为我想做类似的事情。
答案 0 :(得分:1)
您正在寻找的代码位于invoke
method:
def invoke
res = catch(:halt) { yield }
res = [res] if Fixnum === res or String === res
if Array === res and Fixnum === res.first
res = res.dup
status(res.shift)
body(res.pop)
headers(*res)
elsif res.respond_to? :each
body res
end
nil # avoid double setting the same response tuple twice
end
需要注意几个怪癖。例如,如果您返回散列,Sinatra将看到它响应每个并将其视为正文,但由于它不会产生字符串,因此当Web服务器尝试发送内容时,这可能会导致错误或意外结果。此外,机架规范还说明了这一状态:“当解析为整数(to_i)时,它必须大于或等于100”,因此你应该能够传递一个像"200"
这样的字符串,它将被转换为to_i
,但Sinatra只寻找Fixnums,这违背了它的主张“你可以返回任何可能是有效的Rack响应的对象”。