Skip to content

Instantly share code, notes, and snippets.

@elskwid
Last active December 18, 2015 16:29
Show Gist options
  • Save elskwid/5811336 to your computer and use it in GitHub Desktop.
Save elskwid/5811336 to your computer and use it in GitHub Desktop.
module Enuma
def enumerated(type_name, *members, &block)
@enums = []
type_class = const_set(type_name, Enuma::Type.new(*members))
instance_eval(&block)
finalize(@enums, type_class)
end
def enum(*values)
@enums << values
end
def finalize(enums, type_class)
enuma_class = Class.new(Enuma::Types)
@enuma = enuma_class.new(enums, type_class)
all = const_set("ALL", @enuma.all)
all.each do |type|
const_set(type.first.upcase, type.first)
end
end
def method_missing(method, *args, &block)
@enuma.respond_to?(method) ? @enuma.send(method, *args, &block) : super
end
def respond_to_missing?(method, include_private = false)
@enuma.respond_to?(method, include_private) || super
end
class Type < Struct
alias_method :to_ary, :to_a
def self.call
new
end
end
class Types
def initialize(types, struct)
@struct = struct
@all = [].tap { |all| types.each{ |type| all << @struct.new(*type) } }
end
def all
@all
end
def each(&block)
all.each(&block)
end
def find(key)
all.find(@struct){ |type| type.first == key }
end
alias_method :[], :find
end
end
class Colors
extend Enuma
enumerated("Color", :color, :name) do
enum "red", "Red"
enum "blue", "Blue"
enum "goldenrod", "Goldenrod"
enum "burnt_sienna", "Burnt Sienna"
def self.colors
all.map(&:color)
end
def self.names
all.map(&:name)
end
end
end
puts Colors::ALL.inspect
#=> [#<struct Colors::Color color="red", name="Red">, #<struct Colors::Color color="blue", name="Blue">, #<struct Colors::Color color="goldenrod", name="Goldenrod">, #<struct Colors::Color color="burnt_sienna", name="Burnt Sienna">]
puts Colors.all.inspect
#=> [#<struct Colors::Color color="red", name="Red">, #<struct Colors::Color color="blue", name="Blue">, #<struct Colors::Color color="goldenrod", name="Goldenrod">, #<struct Colors::Color color="burnt_sienna", name="Burnt Sienna">]
puts Colors.all.first.inspect
#=> #<struct Colors::Color color="red", name="Red">
puts Colors.colors.inspect
#=> ["red", "blue", "goldenrod", "burnt_sienna"]
puts Colors.names.inspect
#=> ["Red", "Blue", "Goldenrod", "Burnt Sienna"]
puts Colors::RED.inspect
#=> "red"
puts Colors::BURNT_SIENNA.inspect
#=> "burnt_sienna"
puts Colors.find("goldenrod").inspect
#=> #<struct Colors::Color color="goldenrod", name="Goldenrod">
puts Colors["blue"].inspect
#=> #<struct Colors::Color color="blue", name="Blue">
puts Colors.find("indigo").inspect
#=> #<struct Colors::Color color=nil, name=nil>
@smoil
Copy link

smoil commented Jun 19, 2013

No Toasted Cinnamon??

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