Skip to content

Instantly share code, notes, and snippets.

@alainravet
Last active December 16, 2015 17:49
Show Gist options
  • Select an option

  • Save alainravet/5473041 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

burtlo commented Apr 28, 2013

I like it.

@leucos
Copy link
Copy Markdown

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