Class: Degu::Renum::EnumeratedValue

Inherits:
Object
  • Object
show all
Extended by:
Enumerable, Forwardable
Includes:
Comparable
Defined in:
lib/degu/renum/enumerated_value.rb

Overview

This is the superclass of all enumeration classes. An enumeration class is Enumerable over its values and exposes them by numeric index via []. Values are also comparable, sorting into the order in which they’re declared.

Defined Under Namespace

Classes: Field

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ EnumeratedValue

Creates an enumerated value named name with a unique autoincrementing index number.



187
188
189
190
191
# File 'lib/degu/renum/enumerated_value.rb', line 187

def initialize name
  @name = name.to_s.freeze
  @index = self.class.values.size
  self.class.values << self
end

Instance Attribute Details

#indexObject (readonly) Also known as: id, bitfield_index

Index of this enumerated value as an integer.



171
172
173
# File 'lib/degu/renum/enumerated_value.rb', line 171

def index
  @index
end

#nameObject (readonly)

Name of this enumerated value as a string.



168
169
170
# File 'lib/degu/renum/enumerated_value.rb', line 168

def name
  @name
end

Class Method Details

.[](index) ⇒ Object

Returns the enum value for index. If index is an Integer the index-th enum value is returned. Otherwise index is converted into a String. For strings that start with a capital letter the with_name method is used to determine the enum value with the name index. If the string starts with a lowercase letter it is converted into camelcase first, that is foo_bar will be converted into FooBar, before with_name is called with this new value.



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/degu/renum/enumerated_value.rb', line 133

def [](index)
  case index
  when Integer
    values[index]
  when self
    values[index.index]
  else
    name = index.to_s
    case name
    when /\A(\d+)\Z/
      return values[$1.to_i]
    when /\A[a-z]/
      name = name.gsub(/(?:\A|_)(.)/) { $1.upcase }
    end
    with_name(name)
  end
end

._load(string) ⇒ Object

Returns the enum instance stored in the marshalled string string.



152
153
154
# File 'lib/degu/renum/enumerated_value.rb', line 152

def _load(string)
  with_name Marshal.load(string)
end

.definition_extension(*names, &block) ⇒ Object

Adds an enum definition extension method to be able to define methods on newly created enum and use them

inside the definition of enumeration values.
This method accepts both module names and block to extend the enum
Use it as first expression after the `enum :MyEnumName do` enum definition


24
25
26
27
28
29
30
31
32
# File 'lib/degu/renum/enumerated_value.rb', line 24

def definition_extension(*names, &block)
  eigenclass = class << self; self; end
  unless names.empty?
    names.each do |name|
      eigenclass.__send__(:include, name)
    end
  end
  eigenclass.send(:class_eval, &block) if block
end

.field(name, options = {}, &block) ⇒ Object

Defines a field with the name name, the options options and the block block. The only valid option at the moment is :default which is the default value the field is initialized with.



106
107
108
109
110
111
# File 'lib/degu/renum/enumerated_value.rb', line 106

def field(name, options = {}, &block)
  name = name.to_sym
  fields.delete_if { |f| f.name == name }
  fields << field = Field.new(name, options, block)
  instance_eval { attr_reader field.name }
end

.field_namesObject



51
52
53
# File 'lib/degu/renum/enumerated_value.rb', line 51

def field_names
  all.map(&:field_name)
end

.fieldsObject

Returns an array of all fields defined on this enum.



99
100
101
# File 'lib/degu/renum/enumerated_value.rb', line 99

def fields
  @fields ||= []
end

.namesObject



43
44
45
# File 'lib/degu/renum/enumerated_value.rb', line 43

def names
  all.map(&:name)
end

.underscored_namesObject



47
48
49
# File 'lib/degu/renum/enumerated_value.rb', line 47

def underscored_names
  all.map(&:underscored_name)
end

.valuesObject Also known as: all

Returns an array of values in the order they’re declared.



37
38
39
# File 'lib/degu/renum/enumerated_value.rb', line 37

def values
  @values ||= []
end

.values_by_nameObject

Returns a hash that maps names to their respective values values.



119
120
121
122
123
124
# File 'lib/degu/renum/enumerated_value.rb', line 119

def values_by_name
  @values_by_name ||= values.inject({}) do |memo, value|
    memo[value.name] = value
    memo
  end.freeze
end

.with_name(name) ⇒ Object

Returns the value with the name name and returns it.



114
115
116
# File 'lib/degu/renum/enumerated_value.rb', line 114

def with_name name
  values_by_name[name.to_s]
end

Instance Method Details

#<=>(other) ⇒ Object

Sorts enumerated values into the order in which they’re declared.



214
215
216
217
218
219
220
# File 'lib/degu/renum/enumerated_value.rb', line 214

def <=>(other)
  if self.class === other
    index <=> other.index
  elsif other_value = self.class[other]
    self <=> other_value
  end
end

#==(other) ⇒ Object



222
223
224
225
226
227
228
229
230
231
# File 'lib/degu/renum/enumerated_value.rb', line 222

def ==(other)
  case self <=> other
  when nil
    nil
  when 0
    true
  else
    false
  end
end

#_dump(limit = -1)) ⇒ Object

Returns a marshalled string for this enum instance.



234
235
236
# File 'lib/degu/renum/enumerated_value.rb', line 234

def _dump(limit = -1)
  Marshal.dump(name, limit)
end

#as_json(opts = {}, *a) ⇒ Object

Returns an enum (actually more a reference to an enum) serialized as a JSON document.



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/degu/renum/enumerated_value.rb', line 251

def as_json(opts = {}, *a)
  opts ||= {}
  obj = {
    JSON.create_id => self.class.name,
    :name          => name,
  }
  case fields_opt = opts[:fields]
  when nil, false
  when true
    set_fields obj, self.class.fields
  when Array
    fields_opt = fields_opt.map(&:to_sym)
    set_fields obj, self.class.fields.select { |field| fields_opt.include?(field.name) }
  else
    raise ArgumentError, "unexpected fields option #{fields_opt.inspect}"
  end
  obj.as_json(opts)
end

#field_nameObject



181
182
183
# File 'lib/degu/renum/enumerated_value.rb', line 181

def field_name
  "#{self.class.name.underscore.singularize}_#{underscored_name}"
end

#init(*args) ⇒ Object

This is the standard init method method which has an arbitrary number of arguments. If the last argument is a Hash and its keys are defined fields their respective values will be used to initialize the fields. If you want to use this method from an enum and define your own custom init method there, don’t forget to call super from your method.



198
199
200
201
202
203
204
# File 'lib/degu/renum/enumerated_value.rb', line 198

def init(*args)
  if Hash === options = args.last
    for field in self.class.fields
      instance_variable_set "@#{field}", field.default_value(self, options)
    end
  end
end

#json_create(data) ⇒ Object

Fetches the correct enum determined by the deserialized JSON document.



159
160
161
# File 'lib/degu/renum/enumerated_value.rb', line 159

def json_create(data)
  JSON.deep_const_get(data[JSON.create_id])[data['name']]
end

#set_fields(obj, fields) ⇒ Object

Set the given fields in the obj hash



240
241
242
243
244
245
246
247
# File 'lib/degu/renum/enumerated_value.rb', line 240

def set_fields(obj, fields)
  fields.each do |f|
    name = f.name
    value = instance_variable_get("@#{name}")
    value.nil? and next
    obj[name] = value
  end
end

#to_json(opts = {}, *a) ⇒ Object



270
271
272
273
274
# File 'lib/degu/renum/enumerated_value.rb', line 270

def to_json(opts = {}, *a)
  obj = as_json(opts)
  opts.respond_to?(:fields) and opts.delete(:fields)
  obj.to_json(opts, *a)
end

#to_sObject

Returns the fully qualified name of the constant referring to this value. Don’t override this if you’re using Renum with the constantize_attribute plugin, which relies on this behavior.



209
210
211
# File 'lib/degu/renum/enumerated_value.rb', line 209

def to_s
  "#{self.class}::#{name}"
end

#underscored_nameObject



177
178
179
# File 'lib/degu/renum/enumerated_value.rb', line 177

def underscored_name
  name.underscore
end