In Sinatra(Ruby), How to Create Global Variables Which Are Assigned Values Only Once in the Application Lifetime

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


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).

Can I create global variables that work accross routes in Sinatra (Ruby)?

Try something like this maybe?

require 'sinatra'
require './models/questionaire_manager'

set :bind, '0.0.0.0'
set :port, ENV['PORT']
enable :sessions
set :session_secret, 'SecretString#!$%'

helpers do
def quiz_manager
@questionaire = session[:quiz_manager] ||= Questionaire_Manager.new 0
end
end

get '/' do
# Uncomment the line below if you intend to create a new quiz each time
# session[:quiz_manager] = nil
quiz_manager # Initializes the session variable
erb :index
end

post '/' do
quiz_manager.number = params[:number]
redirect '/quiz'
end

get '/quiz' do
quiz_manager.genQuestionaire
erb :quiz
end

post '/quiz' do
redirect '/results'
end

get '/results' do
@number = quiz_manager.number
erb :results
end

Edit:

To clarify what this is doing -- I've created a helper method called quiz_manager that initializes session[:quiz_manager] if it hasn't already been set - This will persist between routes. I'm also setting the class variable @questionnaire so that you can access it within your views.

How do I set a global variable in Sinatra depending on the production or development environment?

Request is not available at the top level, only inside request handlers.

Write a method instead of a global setting, e.g.:

def location(request)
production? ? request.location.city : 'Melbourne'
end

Create object globally in Sinatra

If you want a globally accessible variable, just use the $ notation:

$myobj = MyObject.new
... more code
$myobj.some_method

However, a slightly more elegant solution might be something along these lines:

require 'sinatra/base'

class MyApp < Sinatra::Base
set :sessions, true
set :my_obj, MyObject.new

get '/' do
# call settings.my_obj
end
end

Use PORT environment variable in Rack/Sinatra

rackup takes -p PORT argument.

You can do:

rackup -p $PORT

In config.ru you can also define the options in a comment on the first line:

#\ -p 9090

I'm not sure if that can handle $PORT.

If you look at the source code for rackup, it's very simple:

#!/usr/bin/env ruby
# frozen_string_literal: true

require "rack"
Rack::Server.start

That's the whole file.

Rack::Server.start accepts an options hash as parameter and one of the options is :Port.

You could make your own start.sh that says:

#!/usr/bin/env ruby
# frozen_string_literal: true

require "rack"
Rack::Server.start(Port: ENV['PORT'] || 3000)


Related Topics



Leave a reply



Submit