Skip to content

Instantly share code, notes, and snippets.

@Musfuut
Created December 29, 2009 12:40
Show Gist options
  • Save Musfuut/265284 to your computer and use it in GitHub Desktop.
Save Musfuut/265284 to your computer and use it in GitHub Desktop.
# I've been playing around with Sinatra for a short while.
# I had heard that it was possible to maintain things like
# persistent database connections, etc. I became curious if
# it would be possible to share a variable between clients
# accessing my Sinatra app. I was especially interested in
# how this interacted and differed from the sessions variable
# available with enable :sessions and I like to poke around
# in things. I've been told that I should never attempt to
# use a global-like variable in rack/rails/sinatra and while
# it may be a very bad way to do things, it may still have
# its use.
#
# When I initially coded a test app for this it
# worked, it used simple '/something' route patterns and I
# was excited. However soon after I hit a most interesting
# bug; a global-like variable that suddenly became a clone
# breaking my beautiful world.
#
# After about 8 hours of work I finally figured out a work-
# around for it. The original bug still exists and is still
# just as puzzling but at least the following code works
# regardless. I have decided to demonstrate the problem
# alongside the solution.
require 'rubygems'
require 'sinatra'
# I had tried 'data = "none"' and also 'musfuut_data = "data"' on the suggestion
# that I may be conflicting with an existing variable name. I also tried
# '@musfuut_data = "none"', however I finally tried '@@musfuut_data = "none"'
# which worked like a charm.
old_way = "none"
@@musfuut_data = "none"
before do
content_type("text/plain") # Makes output more console friendly
end
# The following route handlers worked from the start but have been updated
# for the new variable name.
get '/show' do
"Variables set to: #{old_way} and #{@@musfuut_data} (They should always match)\n"
end
get '/one' do
old_way = "one"
@@musfuut_data = "one"
"Variables set to: #{old_way} and #{@@musfuut_data}\n"
end
get '/two' do
old_way = "two"
@@musfuut_data = "two"
"Variables set to: #{old_way} and #{@@musfuut_data}\n"
end
# It is an important reminder that this route handler also worked.
#
# /getset?word=three
#
get '/getset' do
old_way = params[:word]
@@musfuut_data = params[:word]
"Variables set to: #{old_way} and #{@@musfuut_data}\n"
end
# This route handler is the one that caused all the problems and the long
# search for an answer I still do not have. At least there is a work around.
#
# /pathset/four
#
get '/pathset/:word' do
old_way = params[:word]
@@musfuut_data = params[:word]
"Variables set to: #{old_way} and #{@@musfuut_data}\n"
end
# I should note that in the previous route handler that changing
# 'old_way = params[:word]' to 'old_way = "five"' worked so the bug wasn't
# caused by the pattern '/path/:word' alone.
# So for some reason in '/getset' (/getset?word=three) 'old_way = params[:word]'
# works and sets old_way to the word. While in '/pathset/:word' (/pathset/four)
# 'old_way = params[:word]' works!
# So it is the combination of the path and params that causes the odd behavior.
# Test results
# > /show
# < Variables set to: none and none (They should always match)
#
# > /one
# < Variables set to: one and one
# > /show
# < Variables set to: one and one (They should always match)
#
# > /two
# < Variables set to: two and two
# > /show
# < Variables set to: two and two (They should always match)
#
# > /getset?word=three
# < Variables set to: three and three
# > /show
# < Variables set to: three and three (They should always match)
#
# > /pathset/four
# < Variables set to: four and four # Note the next result
# > /show
# < Variables set to: three and four (They should always match)
#
# old_way reverts in this case
#
# I have created a shell script to test the above, you can get it at:
# http://gist.github.com/265302
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment