arr*_*rac 28 ruby web-applications sinatra
在Sinatra中,我无法创建在应用程序生命周期中仅赋值一次的全局变量.我错过了什么吗?我的简化代码如下所示:
require 'rubygems' if RUBY_VERSION < "1.9"
require 'sinatra/base'
class WebApp < Sinatra::Base
@a = 1
before do
@b = 2
end
get '/' do
puts @a, @b
"#{@a}, #{@b}"
end
end
WebApp.run!
Run Code Online (Sandbox Code Playgroud)
这导致了
nil
2
Run Code Online (Sandbox Code Playgroud)
在终端和,2
浏览器中.
如果我尝试@a = 1
输入initialize
方法,我会收到错误WebApp.run!
.
我觉得我错过了一些东西,因为如果我不能拥有全局变量,那么如何在应用程序实例化期间加载大数据呢?
before do
似乎每次有来自客户端的请求时都会调用它.
The*_*heo 38
class WebApp < Sinatra::Base
configure do
set :my_config_property, 'hello world'
end
get '/' do
"#{settings.my_config_property}"
end
end
Run Code Online (Sandbox Code Playgroud)
请注意,如果您使用Shotgun或其他一些在每个请求上重新加载代码的Rack runner工具,则每次都会重新创建该值,并且它看起来好像不会只分配一次.在生产模式下运行以禁用重新加载,您将看到它仅在第一个请求时分配(例如,您可以执行此操作rackup --env production config.ru
).
我遇到了类似的问题,我试图@a
使用该initialize
方法初始化实例变量,但每次都会收到异常:
class MyApp < Sinatra::Application
def initialize
@a = 1
end
get '/' do
puts @a
'inside get'
end
end
Run Code Online (Sandbox Code Playgroud)
我最终决定研究Sinatra代码以进行初始化:
# File 'lib/sinatra/base.rb', line 877
def initialize(app = nil)
super()
@app = app
@template_cache = Tilt::Cache.new
yield self if block_given?
end
Run Code Online (Sandbox Code Playgroud)
看起来它确实进行了一些必要的引导,我需要致电super()
。
def initialize
super()
@a = 1
end
Run Code Online (Sandbox Code Playgroud)
这似乎解决了我的问题,一切正常。