Created
June 15, 2010 04:15
-
-
Save JoshCheek/438689 to your computer and use it in GitHub Desktop.
First (test) Rack app: Generates random numbers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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