【问题标题】:When and where does Sinatra's request object exist?Sinatra 的请求对象何时何地存在?
【发布时间】:2023-03-09 12:50:02
【问题描述】:

我很难过我已经尝试了我能想到的一切来解决这个问题,但我一无所获。

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

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

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

使用`instance_eval 或使用改变代码执行上下文的各种方法:

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] 是“获取”

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

【问题讨论】:

  • 我编辑了问题以显示我所做的一些事情。
  • 您可以通过request method 来获得它。至于它是从哪里来的,看源码就知道是attribute of Sinatra::Base,也就是请求到达app的时候是initialised in call!
  • 我试过了,但我得到了undefined method 'request' for Sinatra::Base:Class:。当我做同样的事情而不是要求我做instance_variables.inspect时,我得到[:@conditions, :@routes, :@filters, :@errors, :@middleware, :@prototype, :@extensions, :@templates]。我通过存储对Sinatra::Base的引用来访问它,然后访问它。
  • 你到底想在这里做什么?在您的请求处理代码(路由、助手等)中,您只需调用request。在请求处理代码之外没有请求获取。
  • 检查我的问题,我添加了它,请求方法也是一个实例方法,所以它不会是Sinatra::Base的属性,而是Sinatra::Base实例的属性,有一个区别。我认为真正的问题是这个实例存储在哪里?如果我发现我可以访问它的方法和请求对象。从存储在Sinatra::Wrapper 中的代码来看,它存储在哪里?`

标签: ruby sinatra


【解决方案1】:

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

class MyApp < Sinatra::Base
end

那么MyApp 类的实例化位置取决于您如何启动运行它的网络服务器;一般来说,机架处理程序(根据您使用的 http 服务器可能有不同的类型)将存储 sinatra 应用程序的实例。当一个机架请求进来时,服务器或另一个机架应用程序将call 具有机架环境哈希的应用程序实例。然后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 版本,这样做很可能会破坏你的应用程序。我不建议编写依赖于这些细节的代码。

【讨论】:

    猜你喜欢
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多