class Functional::ValueStruct

A variation on Ruby’s ‘OpenStruct` in which all fields are immutable and set at instantiation. For compatibility with {Functional::FinalStruct}, predicate methods exist for all potential fields and these predicates indicate if the field has been set. Calling a predicate method for a field that does not exist on the struct will return false.

Unlike {Functional::Record}, which returns a new class which can be used to create immutable objects, ‘ValueStruct` creates simple immutable objects.

@example Instanciation

name = Functional::ValueStruct.new(first: 'Douglas', last: 'Adams')

name.first   #=> 'Douglas'
name.last    #=> 'Adams'
name.first?  #=> true
name.last?   #=> true
name.middle? #=> false

@see Functional::Record @see Functional::FinalStruct @see www.ruby-doc.org/stdlib-2.1.2/libdoc/ostruct/rdoc/OpenStruct.html

@!macro thread_safe_immutable_object

Public Class Methods

new(attributes) click to toggle source
# File lib/functional/value_struct.rb, line 30
def initialize(attributes)
  raise ArgumentError.new('attributes must be given as a hash') unless attributes.respond_to?(:each_pair)
  super
  @attribute_hash = {}
  attributes.each_pair do |field, value|
    set_attribute(field, value)
  end
  @attribute_hash.freeze
  ensure_ivar_visibility!
  self.freeze
end

Public Instance Methods

==(other)
Alias for: eql?
[](field)
Alias for: get
each_pair() { |field, value| ... } click to toggle source

Calls the block once for each attribute, passing the key/value pair as parameters. If no block is given, an enumerator is returned instead.

@yieldparam [Symbol] field the struct field for the current iteration @yieldparam [Object] value the value of the current field

@return [Enumerable] when no block is given

# File lib/functional/value_struct.rb, line 77
def each_pair
  return enum_for(:each_pair) unless block_given?
  @attribute_hash.each do |field, value|
    yield(field, value)
  end
end
eql?(other) click to toggle source

Compares this object and other for equality. A ‘ValueStruct` is `eql?` to other when other is a `ValueStruct` and the two objects have identical fields and values.

@param [Object] other the other record to compare for equality @return [Boolean] true when equal else false

# File lib/functional/value_struct.rb, line 98
def eql?(other)
  other.is_a?(self.class) && @attribute_hash == other.to_h
end
Also aliased as: ==
fetch(field, default) click to toggle source

Get the current value of the given field if already set else return the given default value.

@param [Symbol] field the field to get the value for @param [Object] default the value to return if the field has not been set @return [Object] the value of the given field else the given default value

# File lib/functional/value_struct.rb, line 66
def fetch(field, default)
  @attribute_hash.fetch(field.to_sym, default)
end
get(field) click to toggle source

Get the value of the given field.

@param [Symbol] field the field to retrieve the value for @return [Object] the value of the field is set else nil

# File lib/functional/value_struct.rb, line 46
def get(field)
  @attribute_hash[field.to_sym]
end
Also aliased as: []
inspect() click to toggle source

Describe the contents of this object in a string.

@return [String] the string representation of this object

@!visibility private

# File lib/functional/value_struct.rb, line 108
def inspect
  state = @attribute_hash.to_s.gsub(/^{/, '').gsub(/}$/, '')
  "#<#{self.class} #{state}>"
end
Also aliased as: to_s
set?(field) click to toggle source

Check the internal hash to unambiguously verify that the given attribute has been set.

@param [Symbol] field the field to get the value for @return [Boolean] true if the field has been set else false

# File lib/functional/value_struct.rb, line 56
def set?(field)
  @attribute_hash.has_key?(field.to_sym)
end
to_h() click to toggle source

Converts the ‘ValueStruct` to a `Hash` with keys representing each attribute (as symbols) and their corresponding values.

@return [Hash] a ‘Hash` representing this struct

# File lib/functional/value_struct.rb, line 88
def to_h
  @attribute_hash.dup # dup removes the frozen flag
end
to_s()
Alias for: inspect

Protected Instance Methods

method_missing(symbol, *args) click to toggle source

Check the method name and args for signatures matching potential final predicate methods. If the signature matches call the appropriate method

@param [Symbol] symbol the name of the called function @param [Array] args zero or more arguments @return [Object] the result of the proxied method or the ‘super` call

@!visibility private

Calls superclass method
# File lib/functional/value_struct.rb, line 136
def method_missing(symbol, *args)
  if args.length == 0 && (match = /([^\?]+)\?$/.match(symbol))
    set?(match[1])
  elsif args.length == 0 && set?(symbol)
    get(symbol)
  else
    super
  end
end
set_attribute(field, value) click to toggle source

Set the value of the give field to the given value.

@param [Symbol] field the field to set the value for @param [Object] value the value to set the field to @return [Object] the final value of the given field

@!visibility private

# File lib/functional/value_struct.rb, line 123
def set_attribute(field, value)
  @attribute_hash[field.to_sym] = value
end