Class: Literal::Enum

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/literal/enum.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, value) ⇒ Enum

Returns a new instance of Enum.



78
79
80
81
82
# File 'lib/literal/enum.rb', line 78

def initialize(name, value)
	@name = "#{self.class.name}::#{name}"
	@value = value
	@short_name = name.to_s.gsub(/([a-z])([A-Z])/, '\1_\2').downcase!
end

Instance Attribute Details

#nameObject

Returns the value of attribute name.



84
85
86
# File 'lib/literal/enum.rb', line 84

def name
  @name
end

#short_nameObject

Returns the value of attribute short_name.



84
85
86
# File 'lib/literal/enum.rb', line 84

def short_name
  @short_name
end

#valueObject

Returns the value of attribute value.



84
85
86
# File 'lib/literal/enum.rb', line 84

def value
  @value
end

Class Method Details

.cast(value) ⇒ Object



7
8
9
# File 'lib/literal/enum.rb', line 7

def cast(value)
	@values[value]
end

.define(type) ⇒ Object



19
20
21
# File 'lib/literal/enum.rb', line 19

def define(type, &)
	Class.new(self, &).freeze
end

.eachObject



15
16
17
# File 'lib/literal/enum.rb', line 15

def each(&)
	@members.each(&)
end

.method_missing(name, *args, **kwargs) ⇒ Object



23
24
25
26
27
28
# File 'lib/literal/enum.rb', line 23

def method_missing(name, *args, **kwargs, &)
	return super if frozen? || args.length > 1 || kwargs.any?
	return super unless name[0] =~ /[A-Z]/

	new(name, *args, &)
end

.new(name, a = nil, b = nil) ⇒ Object

Raises:



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/literal/enum.rb', line 30

def new(name, a = nil, b = nil, &)
	raise ArgumentError if frozen?

	@values ||= Concurrent::Map.new
	@members ||= Concurrent::Array.new

	if !b && a.is_a?(Proc)
		transitions_to = a
		value = name
	else
		value = a || name
		transitions_to = b
	end

	if self == Literal::Enum
		raise ArgumentError,
			"You can't add values to the abstract Enum class itself."
	end

	if const_defined?(name)
		raise NameError,
			"Name conflict: '#{self.name}::#{name}' is already defined."
	end

	if @values[value]
		raise NameError,
			"Value conflict: the value '#{value}' is defined for '#{cast(value).name}'."
	end

	class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
      def #{name.to_s.gsub(/([a-z])([A-Z])/, '\1_\2').downcase!}?
        @short_name == "#{name.to_s.gsub(/([a-z])([A-Z])/, '\1_\2').downcase!}"
      end
	RUBY

	member = super(name, value)
	member.define_singleton_method(:transitions_to, transitions_to) if transitions_to
	member.instance_eval(&) if block_given?
	member.freeze

	const_set(name, member)
	@members << member
	@values[value] = member

	member
end

.valuesObject



11
12
13
# File 'lib/literal/enum.rb', line 11

def values
	@values.keys
end