Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Created June 15, 2010 04:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/438689 to your computer and use it in GitHub Desktop.
Save JoshCheek/438689 to your computer and use it in GitHub Desktop.
First (test) Rack app: Generates random numbers.
# RESULT CAN BE SEEN AT http://furious-day-14.heroku.com/
#
#
# Sat down to watch this video about rack http://confreaks.net/videos/49-mwrc2009-in-a-world-of-middleware-who-needs-monolithic-applications
# About 17 min in at the moment, figured I'd verify what the guy was saying. Ended up with this simple script to generate random numbers.
# Figured I'd see if I could get it on heroku, looked up this blog I had read a few months ago http://blog.heroku.com/archives/2009/3/5/32_deploy_merb_sinatra_or_any_rack_app_to_heroku/
# Tried it all out, and it worked!
#
# Regarding the code, I don't think it would scale well. I'll need to spend some time thinking about the implications of this sort of environment.
# For example: validating urls, handling exceptions, giving help file, generating content all in one class gets some ugly coupling between methods.
# Though, I think rack is supposed to be at a lower level than I as a user would ever experience, so I don't think it's really meant for this type of use.
# They just point out that you can use it like this, b/c it's a cool enough idea to get people like me to go try it out.
class RandomNumberGenerator
MAX_COUNT = 1000
def call(env)
begin
set_path env['PATH_INFO']
raise ArgumentError.new("Min is greater than max") if rand_min > rand_max
[ 200 , { 'Content-Type' => 'text/plain' } , content(env) ]
rescue => e
[ 400 , { 'Content-Type' => 'text/plain' } , usage(env,e) ]
end
end
def content(env)
min = rand_min
max = rand_max
count = rand_count
difference = max - min
raise ArgumentError.new("Count is too large") if count > MAX_COUNT
(0...count).map { min + rand(difference).to_i }.join(' ')
end
def set_path(path)
@path = path.split('/').reject { |segment| !segment || segment.empty? }
raise ArgumentError.new("Too many path parameters") if @path.size > 3
raise ArgumentError.new("Path must only contain numbers") if @path.any? { |segment| segment !~ /^-?\d+$/ }
end
def rand_count
if @path.first
@path.first.to_i
else
raise ArgumentError.new("No Arguments")
end
end
def default_max
1000
end
def rand_max
case @path.length
when 2 , 3
@path[-1].to_i
else
default_max
end
end
def default_min
0
end
def rand_min
case @path.length
when 3
@path[1].to_i
else
default_min
end
end
def usage( env , error )
url = env["HTTP_HOST"]
<<-USAGE.gsub(/^ /,'')
Your request should look like one of the following:
#{url}/10 implies count => 10 , min => #{default_min} , max => #{default_max}
#{url}/10/30 implies count => 10 , min => #{default_min} , max => 30
#{url}/10/20/30 implies count => 10 , min => 20 , max => 30
The min must be less than the max.
Only digits are allowed.
Count may not exceed #{MAX_COUNT}
Your values were:
count => #{(rand_count rescue nil) || 'missing'}
min => #{rand_min}
max => #{rand_max}
Your request was not fulfilled because:
#{error.message}
USAGE
end
end
run RandomNumberGenerator.new
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment