Skip to content

Instantly share code, notes, and snippets.

@eladmeidar
Last active December 11, 2015 03:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eladmeidar/9c3e4f2923a4392c8cad to your computer and use it in GitHub Desktop.
Save eladmeidar/9c3e4f2923a4392c8cad to your computer and use it in GitHub Desktop.
Better enum
# Ruby Enum
# ---------
# enum = Enum.new("Apple", "Orange", "Prun")
# enum[:apple] = 0
# enum[0] = :apple
require 'set'
class Enum < Set
class Member
include Comparable
attr_reader :symbol
attr_reader :index
attr_reader :name
def initialize(value, index = 0, name = nil)
@symbol = value.to_sym
@index = index.to_i
@name = name ||= value
end
def <=>(other_member)
self.symbol <=> other_member.symbol
end
end
def initialize(*members)
super()
populate(members)
end
def to_a
super.sort_by(&:index)
end
def each
block_given? or return enum_for(__method__)
self.to_a.each { |o| yield(o) }
self
end
def [](index_or_symbol)
if index_or_symbol.is_a?(Symbol)
return self.select {|member| member.symbol == index_or_symbol }.first
elsif index_or_symbol.is_a?(Integer)
return self.select {|member| member.index == index_or_symbol }.first
end
end
def inspect
ids = (Thread.current[InspectKey] ||= [])
if ids.include?(object_id)
return sprintf('#<%s: {...}>', self.class.name)
end
begin
ids << object_id
return sprintf('#<%s: {%s}>', self.class, to_a.collect(&:name).inspect[1..-2])
ensure
ids.pop
end
end
protected
def populate(members)
members.each_with_index do |member, index|
self.add(Enum::Member.new(member, index)) unless self.to_a.collect(&:name).include?(member)
end
end
end
@seivan
Copy link

seivan commented Jan 16, 2013

I'd like

Enum.new(:does_not_exist => -1, red, blue, gray)
doest_not_exist == -1
red == 0
blue == 1
gray == 2

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