In Sinatra(Ruby), how should I create global variables which are assigned values only once in the application lifetime?

arrac picture arrac · Dec 24, 2010 · Viewed 22.2k times · Source

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 this:

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!

This results in

nil
2

in the terminal and ,2 in the browser.

If I try to put @a = 1 in the initialize method, I'm getting an error in the WebApp.run! line.

I feel I'm missing something because if I can't have global variables, then how can I load large data during application instantiation?

before do seems to get called every time there is a request from the client side.

Answer

Theo picture Theo · Dec 24, 2010
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).