Skip to content

Instantly share code, notes, and snippets.

@alainravet
Last active December 16, 2015 17:49
Show Gist options
  • Save alainravet/5473041 to your computer and use it in GitHub Desktop.
Save alainravet/5473041 to your computer and use it in GitHub Desktop.
# response to http://jumpstartlab.com/news/archives/2013/04/23/the-death-of-ifs
#-----------------
# Commands :
#-----------------
class Command
class Quit ; def execute ; exit end end
class Invalid ; def execute ; puts 'invalid command' end end
class Tweeting ; def execute ; puts "tweeting" end end
class Retweeting ; def execute ; puts "retweeting" end end
class Commenting ; def execute ; puts "commenting" end end
end
#----------------------------------
# Mapping : input -> 1 Command
#----------------------------------
class Commands
MAPPING = Hash.new{ Command::Invalid.new }
def self.register(input, command)
MAPPING[input] = command
end
def self.command_for(input)
MAPPING[input]
end
def self.valid_inputs
MAPPING.keys
end
end
Commands.register 'q', Command::Quit.new
Commands.register 't', Command::Tweeting.new
Commands.register 'r', Command::Retweeting.new
Commands.register 'c', Command::Commenting.new
#----------------------------------
# main loop
#----------------------------------
def show_prompt
puts "Enter a command (one of #{Commands.valid_inputs.join(', ')})" ; true
end
while show_prompt && command = Commands.command_for(STDIN.gets.chomp)
command.execute
end
#----------------------------------
# test input -> command mapping
#----------------------------------
def assert(condition) raise unless condition end
assert Commands.command_for('q').is_a?(Command::Quit)
assert Commands.command_for('t').is_a?(Command::Tweeting)
assert Commands.command_for('r').is_a?(Command::Retweeting)
assert Commands.command_for('c').is_a?(Command::Commenting)
assert Commands.command_for('?').is_a?(Command::Invalid)
assert Commands.command_for(' ').is_a?(Command::Invalid)
#----------------------------------
# test individual commands effect
#----------------------------------
require 'stringio'
def assert_output_is(expected)
$stdout = StringIO.new
yield
unless expected == (actual_result = $stdout.string.chomp)
raise "incorrect output : \n\texpected : #{expected} \n\tfound : #{actual_result}"
end
ensure
$stdout = STDOUT
end
assert_output_is("tweeting" ) { Command::Tweeting .new.execute }
assert_output_is("retweeting" ) { Command::Retweeting.new.execute }
assert_output_is("commenting" ) { Command::Commenting.new.execute }
assert_output_is("invalid command") { Command::Invalid .new.execute }
begin
Command::Quit.new.execute
rescue SystemExit
system_exit_triggered = true
ensure
raise "Quit didn't exit" unless system_exit_triggered
end
@burtlo
Copy link

burtlo commented Apr 28, 2013

I like it.

@leucos
Copy link

leucos commented Apr 30, 2013

Limpide. Merci Alain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment