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.

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:

  • (Functional::AbstractStruct)

    the new record subclass

Raises:

  • (ArgumentError)

    no fields specified or an invalid type specification is given



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

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:

  • (Functional::AbstractStruct)

    the new record subclass

Raises:

  • (ArgumentError)

    no fields specified or an invalid type specification is given



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

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