Class: Value::Attributes

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/value-1.0/attributes.rb

Overview

Keeps track of the structure of the attributes associated with a Value object. This is an ordered set of #required, #optional, #splat, and #block arguments to the value object’s initialize method, some or all of which may be #comparable.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(first, *rest, options = {}) ⇒ Attributes

Returns a new instance of Attributes.

Sets up a Value objects attributes FIRST and REST. If the last attribute starts with ‘&’, then the value object’s initialize method may take an optional block. If the last or second to last, depending on the previous sentence, attribute starts with ‘*’, then the value object’s initialize method may take a splat argument. The rest of the attributes are split at the first element that’s an Array. All attributes before this element are required arguments to the value object’s initialize method. The first element that’s an Array and all following elements, which should also be Arrays, are optional arguments to the value object’s initialize method, where the first element of these Arrays is the attribute and the last element is its default value.

Parameters:

  • first (Symbol, Array<Symbol, Object>)
  • rest (Array<Symbol, Array<Symbol, Object>>)
  • options (Hash) (defaults to: {})

Options Hash (options):

  • :comparable (Array<Symbol>, Boolean, nil) — default: nil

    The subset of first and rest that should be used for comparing instances of this value object class, or a truthy value to use the whole set, or a falsy value to use an empty set

Raises:

  • (ArgumentError)

    If any element of COMPARABLE isn’t an element of first and rest



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/value-1.0/attributes.rb', line 34

def initialize(first, *rest)
  options = Hash === rest.last ? rest.pop : {}
  names = [first] + rest
  names.pop if @block = names.last.to_s.start_with?('&') ?
    names.last.to_s[1..-1].to_sym : nil
  names.pop if @splat = (names.last and names.last.to_s.start_with?('*')) ?
    names.last.to_s[1..-1].to_sym : nil
  @required = names.take_while{ |e| not(Array === e) }.map(&:to_sym)
  @optional = names[required.length..-1].map{ |e| [e.first.to_sym, e.last] }
  all = to_a
  @comparable =
    case options[:comparable]
    when Array
      options[:comparable].each{ |e|
        raise ArgumentError, '%p is not among comparable members %s' %
          [e, all.map(&:inspect).join(', ')] unless all.include?(e)
      }
    when false, nil
      []
    else
      all
    end
end

Instance Attribute Details

#blockSymbol? (readonly)

Returns The block attribute.

Returns:

  • (Symbol, nil)

    The block attribute



98
99
100
# File 'lib/value-1.0/attributes.rb', line 98

def block
  @block
end

#comparableArray<Symbol> (readonly)

Returns The comparable attributes.

Returns:

  • (Array<Symbol>)

    The comparable attributes



101
102
103
# File 'lib/value-1.0/attributes.rb', line 101

def comparable
  @comparable
end

#optionalArray<Array<Symbol, Object>> (readonly)

Returns The optional attributes and their defaults.

Returns:

  • (Array<Array<Symbol, Object>>)

    The optional attributes and their defaults



92
93
94
# File 'lib/value-1.0/attributes.rb', line 92

def optional
  @optional
end

#requiredArray<Symbol> (readonly)

Returns The required attributes.

Returns:

  • (Array<Symbol>)

    The required attributes



88
89
90
# File 'lib/value-1.0/attributes.rb', line 88

def required
  @required
end

#splatSymbol? (readonly)

Returns The splat attribute.

Returns:

  • (Symbol, nil)

    The splat attribute



95
96
97
# File 'lib/value-1.0/attributes.rb', line 95

def splat
  @splat
end

Instance Method Details

#==(other) ⇒ Boolean

Returns True if the receiver’s class and its required, optional, splat, and block attributes ‘#==` those of OTHER.

Returns:

  • (Boolean)

    True if the receiver’s class and its required, optional, splat, and block attributes ‘#==` those of OTHER



79
80
81
82
83
84
85
# File 'lib/value-1.0/attributes.rb', line 79

def ==(other)
  self.class == other.class and
    required == other.required and
    optional == other.optional and
    splat == other.splat and
    block == other.block
end

# {|attribute| ... } ⇒ Object #Enumerator<Symbol>

Overloads:

  • # {|attribute| ... } ⇒ Object

    Enumerates the attributes.

    Yield Parameters:

    • attribute (Symbol)
  • #Enumerator<Symbol>

    Returns An Enumerator over the attributes.

    Returns:

    • (Enumerator<Symbol>)

      An Enumerator over the attributes

Yields:



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/value-1.0/attributes.rb', line 64

def each
  return enum_for(__method__) unless block_given?
  required.each do |name|
    yield name
  end
  optional.each do |name, _|
    yield name
  end
  yield splat if splat
  yield block if block
  self
end