【问题标题】:Access helper module class in Sinatra from routes从路由访问 Sinatra 中的辅助模块类
【发布时间】:2014-08-23 02:36:48
【问题描述】:

我正在编写一个模块化的Sinatra 应用程序。我写了一个helper module 来处理oauth 调用。

现在我使用global variable(例如$squick ||= Skroutz::Query.new)来创建通过我的路由共享的对象(参见here)。

然后J. Hass 提到我应该避免使用全局变量,因为它不是线程安全的,他可能是对的。

但是,我不知道如何创建可以通过我的所有路由访问的此类的实例。我尝试了几件事,但没有任何效果。不过,我确信它可以通过多种方式完成。

谢谢

ps。请进行描述,了解我在做什么对我来说很重要:-)

【问题讨论】:

    标签: ruby sinatra


    【解决方案1】:

    根据:http://www.sinatrarb.com/configuration.html,你可以这样做:

    require 'sinatra/base'
    
    module Animals
      class Dog
      end
    end
    
    class MyApp < Sinatra::Base
      set :dog, Animals::Dog.new
    
      get '/' do
        puts "The object_id in '/' is: #{settings.dog.object_id}"
      end
    
      get '/val' do
        "The object_id in '/val' is: #{settings.dog.object_id}"
      end
    
      run! if app_file == $0
    end
    

    如果您在浏览器中输入以下网址:

    http://localhost:4567/
    

    ...然后在浏览器中输入此网址:

    http://localhost:4567/val
    

    ...然后检查服务器窗口中输出的 id,它将与网页上显示的 id 相同。

    但是,我不知道设置对象是否是线程安全的。根据 Sinatra README:

    请求/实例范围

    对于每个传入的请求,应用程序类的一个新实例 已创建,并且所有处理程序块都在该范围内运行。

    但是上面的结果显示,第二个请求可以访问与第一个请求相同的 Dog 对象,这意味着第二个请求可以更改第一个请求看到的 Dog 对象。从文档或我的谷歌搜索中,一个请求是否可以在另一个请求读取 Dog 对象的同时更改 Dog 对象并不清楚。

    【讨论】:

    • @atmosx,您可能不应该接受我的回答,因为我不知道它是否是线程安全的。给其他人一些时间来回应。
    • 好的,感谢您的指点。刚刚尝试了您的方法,不幸的是无法访问该对象,因为我最终加载了帮助程序:github.com/atmosx/pritory/blob/master/pritory.rb 但您给了我一个想法,尽管现在非常优雅。 :-)
    • @atmosx,在代码末尾而不是文件顶部有 require 的原因是什么?
    • 我认为这是一种必要的邪恶。请记住,我过去有一个问题,使用相同的骨架,但事实并非如此。刚刚尝试过并且有效。我的坏:-)
    • @atmosx, A require(或require_relative) 执行文件中的代码,因此您必须注意所需文件中的代码不依赖于其他代码在它之前,例如,如果所需的文件提到 MyApp,那么 require 必须在 MyApp 的定义之后。但是,如果您的代码中的某些内容需要创建某个类的实例,例如Dog,然后必须首先定义 Dog 类,因此您必须将 Dog 类的 require 放在想要创建 Dog 实例的代码之前。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多