class Good

Constants

VERSION

Public Class Methods

coerce(coercable) click to toggle source
# File lib/good.rb, line 28
def self.coerce(coercable)
  case coercable
  when self then coercable
  when Hash then new(coercable)
  else raise TypeError, "Unable to coerce #{coercable.class} into #{self}"
  end
end
generate(mutable, *members, &block) click to toggle source
# File lib/good.rb, line 22
def self.generate(mutable, *members, &block)
  Class.new do
    mutable ? attr_accessor(*members) : attr_reader(*members)

    const_set(:MEMBERS, members.map(&:to_sym).freeze)

    def self.coerce(coercable)
      case coercable
      when self then coercable
      when Hash then new(coercable)
      else raise TypeError, "Unable to coerce #{coercable.class} into #{self}"
      end
    end


    if mutable
      def initialize(attributes = {})
        Good.validate_constructor_attributes(attributes, self.class::MEMBERS)
        attributes.each { |k, v| send("#{k}=", v) }
      end
    else
      def initialize(attributes = {})
        Good.validate_constructor_attributes(attributes, self.class::MEMBERS)
        attributes.each { |k, v| instance_variable_set(:"@#{k}", v) }
      end
    end

    def attributes
      {}.tap { |h| self.class::MEMBERS.each { |m| h[m] = send(m) } }
    end

    def members
      self.class::MEMBERS.dup
    end

    def values
      self.class::MEMBERS.map { |m| send(m) }
    end

    def merge(attributes={})
      self.class.new(self.attributes.merge(attributes))
    end

    def ==(other)
      other.is_a?(self.class) && attributes == other.attributes
    end

    def eql?(other)
      self == other
    end

    def hash
      attributes.hash
    end

    class_eval(&block) if block
  end
end
new(attributes = {}) click to toggle source
# File lib/good.rb, line 38
def initialize(attributes = {})
  Good.validate_constructor_attributes(attributes, self.class::MEMBERS)
  attributes.each { |k, v| send("#{k}=", v) }
end
validate_constructor_attributes(attributes, allowed) click to toggle source
# File lib/good.rb, line 16
def self.validate_constructor_attributes(attributes, allowed)
  if (unrecognized = attributes.keys.map(&:to_sym) - allowed).any?
    raise ArgumentError, "Unrecognized parameter(s): #{unrecognized.join(', ')}"
  end
end

Public Instance Methods

==(other) click to toggle source
# File lib/good.rb, line 65
def ==(other)
  other.is_a?(self.class) && attributes == other.attributes
end
attributes() click to toggle source
# File lib/good.rb, line 49
def attributes
  {}.tap { |h| self.class::MEMBERS.each { |m| h[m] = send(m) } }
end
eql?(other) click to toggle source
# File lib/good.rb, line 69
def eql?(other)
  self == other
end
hash() click to toggle source
# File lib/good.rb, line 73
def hash
  attributes.hash
end
members() click to toggle source
# File lib/good.rb, line 53
def members
  self.class::MEMBERS.dup
end
merge(attributes={}) click to toggle source
# File lib/good.rb, line 61
def merge(attributes={})
  self.class.new(self.attributes.merge(attributes))
end
values() click to toggle source
# File lib/good.rb, line 57
def values
  self.class::MEMBERS.map { |m| send(m) }
end