In Sinatra, I\'m unable to create global variables which are assigned values only once in the application lifetime. Am I missing something? My simplified code looks like thi
I ran into a similar issue, I was trying to initialize an instance variable @a
using the initialize
method but kept receiving an exception every time:
class MyApp < Sinatra::Application
def initialize
@a = 1
end
get '/' do
puts @a
'inside get'
end
end
I finally decided to look into the Sinatra code for initialize:
# 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
Looks like it does some necessary bootstrapping and I needed to call super()
.
def initialize
super()
@a = 1
end
This seemed to fix my issue and everything worked as expected.
You could use OpenStruct.
require 'rubygems'
require 'sinatra'
require 'ostruct'
configure do
Struct = OpenStruct.new(
:foo => 'bar'
)
end
get '/' do
"#{Struct.foo}" # => bar
end
You can even use the Struct class in views and other loaded files.
Another option:
helpers do
def a
a ||= 1
end
end
class WebApp < Sinatra::Base
configure do
set :my_config_property, 'hello world'
end
get '/' do
"#{settings.my_config_property}"
end
end
Beware that if you use Shotgun, or some other Rack runner tool that reloads the code on each request the value will be recreated each time and it will look as if it's not assigned only once. Run in production mode to disable reloading and you will see that it's only assigned on the first request (you can do this with for example rackup --env production config.ru
).