Sha256: c970f13b9ec15383d018d82a4d97d062c165f344dac207530bc1bf114bb6d470
Contents?: true
Size: 1.97 KB
Versions: 1
Compression:
Stored size: 1.97 KB
Contents
# encoding: utf-8 module EnumField class Builder METHODS = [:all, :names, :find_by_id, :find, :first, :last] def initialize(target) @target = target @next_id = 0 @id2obj = {} @name2obj = {} @sorted = [] end def member(name, options = {}) obj, candidate_id = process_options(options) assign_id(obj, candidate_id) define_in_meta(name) { obj } save(name, obj) obj.freeze end def all @sorted.dup end def names @name2obj.keys end def find(id) find_by_id(id) or raise EnumField::ObjectNotFound end def find_by_id(id) case id when Integer, String, Float, Fixnum then @id2obj[id.to_i] when Array then id.inject([]) do |items, value| if value && value.respond_to?(:to_i) items << @id2obj[value.to_i] end items end end end def first; @sorted.first; end def last; @sorted.last; end private def define_in_meta(name, &block) metaclass = class << @target; self; end metaclass.send(:define_method, name, &block) end def assign_id(obj, candidate_id) id = new_id(candidate_id) obj.instance_variable_set(:@id, id) end def new_id(candidate) validate_candidate_id(candidate) candidate || find_next_id end def validate_candidate_id(id) raise EnumField::InvalidId.new(id) unless id.nil? || id.is_a?(Integer) && id > 0 raise EnumField::RepeatedId.new(id) if @id2obj.has_key?(id) end def find_next_id @next_id += 1 while @id2obj.has_key?(@next_id) || @next_id <= 0 @next_id end def process_options(options) raise EnumField::InvalidOptions unless options.reject {|k,v| k == :object || k == :id}.empty? [options[:object] || @target.new, options[:id]] end def save(name, obj) @id2obj[obj.id] = obj @sorted << obj @name2obj[name] = obj end end end
Version data entries
1 entries across 1 versions & 1 rubygems
Version | Path |
---|---|
galetahub-enum_field-0.3.0 | lib/enum_field/builder.rb |