Skip to content

Instantly share code, notes, and snippets.

@hoverlover
Created May 25, 2010 16:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hoverlover/413314 to your computer and use it in GitHub Desktop.
Save hoverlover/413314 to your computer and use it in GitHub Desktop.
Module to facility the enumeration of constants
# This module should be used for situations where enumerating over constant values is desired.
# This facilitates keeping the code DRY by keeping the constant values defined in one place, and
# still having the ability to enumerate over them wherever they are needed.
#
# Example use cases:
#
# * defining constants for possible field values in an AR object and including this module to
# provide access to the values in a 'validates_inclusion_of' validation
# * defining constants for select box values in a view and including this module to allow them to be
# enumerated over in the select tag
module EnumerableConstants
def EnumerableConstants.included(mod)
class << mod
include Enumerable
def enumerable(*consts)
@enumerable_consts = consts unless consts.empty?
end
# Yields each constant value to &block. By default, all constants defined by the
# including class are yielded. If specific constants are to be yielded, call
# EnumerableConstants#enumerable(*consts) before calling this method.
def each(&block)
consts = @enumerable_consts || self.constants.grep(/[^a-z][A-Z_]+/)
consts.each do |const|
yield self.const_get(const)
end
end
# #each_constant is provided as syntactic sugar for situations where it may be more appropriate than #each
alias_method :each_constant, :each
end
end
end
class Program
def do_stuff
end
class Statuses
include EnumerableConstants
PENDING = 'pending'
RUNNING = 'running'
DONE = 'done'
end
end
Program::Statuses::DONE
#=> "done"
Program::Statuses.collect
#=> ["pending", "done", "running"]
class Program
include EnumerableConstants
enumerable :PENDING, :RUNNING, :DONE
PENDING = 'pending'
RUNNING = 'running'
DONE = 'done'
CONST_WE_DONT_WANT_EXPOSED_IN_ITERATION = 'not in iterate'
def do_stuff
end
end
Program::CONST_WE_DONT_WANT_EXPOSED_IN_ITERATION
#=> "not in iterate"
Program.each_constant{|c| puts c}
#=> pending
#=> running
#=> done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment