Last active
September 22, 2016 09:05
-
-
Save mieko/8d7413baf7547b7995c4a80936a282e1 to your computer and use it in GitHub Desktop.
switch in Ruby
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
class Switch < BasicObject | |
def initialize(&body) | |
fail ArgumentError, 'switch body required' unless body | |
@cases = [] | |
@receiver = body.binding.receiver | |
instance_eval(&body) | |
end | |
def given(*spec, &block) | |
fail ArgumentError 'block required' unless block | |
@cases.push([spec, block]) | |
end | |
def default(&block) | |
fail ArgumentError 'block required' unless block | |
fail ArgumentError 'default already specified' if @default | |
@default = block | |
end | |
def evaluate(value) | |
@cases.each do |case_list, handler| | |
case_list.each do |case_item| | |
if case_item === value | |
return @receiver.instance_exec(case_item, value, &handler) | |
end | |
end | |
end | |
@default.call(value) if @default | |
end | |
end | |
def switch(value, &body) | |
Switch.new(&body).evaluate(value) | |
end | |
result = switch($stdin.gets.chomp) do | |
given '0' do | |
'zero' | |
end | |
given '1'..'3' do | |
'one through three' | |
end | |
given /^4$/, /^four$/ do |m| | |
"four, via #{m}" | |
end | |
default do | |
"unknown" | |
end | |
end | |
puts result |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment