Sinatra的请求对象何时何地存在?

时间:2015-02-20 12:50:13

标签: ruby sinatra

我很难过我已经尝试了所有我能想到的事情来解决这个问题而我什么都没有。

Sinatra的请求对象何时开始存在以及它实际存在于何处以及如何从任何地方获取它?即继承自继承自Sinatra::Base的类的类的另一个类。

我已经设法从this question了解它的存在,但我似乎无法再进一步了解。 我尝试过的事情:

def self.request
   self.superclass.superclass.superclass.request
end

使用`instance_eval或using:

更改代码执行上下文的各种方法
def self.method_added method_name
  a = self.new.method(method_name)
    def self.define_method method_name do
      a.call
    end
end 

以及我能想到的任何其他内容,但无论我做什么request总是为零,所以我再次询问请求对象在请求期间何时何地出现?

编辑:

没有冒犯,但是如何判断我在问什么呢?

这是问题,它在标题中:

When and where does Sinatra's request object exist?

Sinatra有一个请求对象,该对象什么时候开始存在? (在代码执行期间它不是什么时候?)

当它确实存在时,它存在于哪里,Sinatra::Base Sinatra::Base的实例或`Wrapper或其他地方?

编辑:

这就是我正在做的事情:

在这个例子中

r[:action]是'get'

r[:url]是'/'

methodget_root

instance是一个存储self.new的变量,因此我可以访问任何实例方法。

            def method_added method
                return if Delegation::SIN_DSL[:basic].include?(method)
                r,p = get_r_data method
                m = self.instance.method(method)
                self.send r[:action], r[:url].first, (@options || {}) do         
                    (m.arity < 1 ) ?  m.call : m.call(*p)                                      
                end
                @options = nil

            end

1 个答案:

答案 0 :(得分:1)

sinatra应用程序是一个机架应用程序。如果你有

class MyApp < Sinatra::Base
end

然后MyApp类被实例化的位置取决于你如何启动运行它的网络服务器;一般来说,机架处理程序(可能是不同类型,具体取决于您正在使用的http服务器)将存储sinatra应用程序的实例。当机架请求进入时,服务器或其他机架应用程序将call具有机架env哈希的应用程序实例。然后,Sinatra::Base#call将执行dup.call!(env),这意味着会生成现有实例的浅表副本,然后在副本上调用call!body of call!是初始化请求对象的位置:

def call!(env) # :nodoc:
  @env      = env
  @request  = Request.new(env)

并且这是您在路由处理程序中引用request时通常调用此实例变量的应用程序的request访问者。

不确定这对你有帮助,但它至少应该回答这个问题。

警告:答案对sinatra v1.4.5有效,但您不应期望它仍然有效。这些实现细节不是公共sinatra API的一部分,并且由于某种原因没有记录 - 您并不打算弄乱它,如果升级sinatra版本,这样做很可能会破坏您的应用程序。我不建议编写依赖于这些细节的代码。