Module: Functional::Record

Extended by:
Record
Included in:
Record
Defined in:
lib/functional/record.rb

Overview

Note:

This is a write-once, read-many, thread safe object that can be used in concurrent systems. Thread safety guarantees cannot be made about objects contained within this object, however. Ruby variables are mutable references to mutable objects. This cannot be changed. The best practice it to only encapsulate immutable, frozen, or thread safe objects. Ultimately, thread safety is the responsibility of the programmer.

An immutable data structure with multiple data fields. A Record is a convenient way to bundle a number of field attributes together, using accessor methods, without having to write an explicit class. The Record module generates new AbstractStruct subclasses that hold a set of fields with a reader method for each field.

A Record is very similar to a Ruby Struct and shares many of its behaviors and attributes. Unlike a # Ruby Struct, a Record is immutable: its values are set at construction and can never be changed. Divergence between the two classes derive from this core difference.

See Also:

Since:

  • 1.0.0

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.new(*fields, &block) ⇒ Functional::AbstractStruct

Create a new record class with the given fields.

Returns:

Raises:

  • (ArgumentError)

    no fields specified or an invalid type specification is given

Since:

  • 1.0.0



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/functional/record.rb', line 36

def new(*fields, &block)
  raise ArgumentError.new('no fields provided') if fields.empty?

  name = nil
  types = nil

  # check if a name for registration is given
  if fields.first.is_a?(String)
    name = fields.first
    fields = fields[1..fields.length-1]
  end

  # check for a set of type/protocol specifications
  if fields.size == 1 && fields.first.respond_to?(:to_h)
    types = fields.first
    fields = fields.first.keys
    check_types!(types)
  end

  build(name, fields, types, &block)
rescue
  raise ArgumentError.new('invalid specification')
end

Instance Method Details

#new(*fields, &block) ⇒ Functional::AbstractStruct

Create a new record class with the given fields.

Returns:

Raises:

  • (ArgumentError)

    no fields specified or an invalid type specification is given

Since:

  • 1.0.0



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/functional/record.rb', line 36

def new(*fields, &block)
  raise ArgumentError.new('no fields provided') if fields.empty?

  name = nil
  types = nil

  # check if a name for registration is given
  if fields.first.is_a?(String)
    name = fields.first
    fields = fields[1..fields.length-1]
  end

  # check for a set of type/protocol specifications
  if fields.size == 1 && fields.first.respond_to?(:to_h)
    types = fields.first
    fields = fields.first.keys
    check_types!(types)
  end

  build(name, fields, types, &block)
rescue
  raise ArgumentError.new('invalid specification')
end