Module: Functional::Union

Extended by:
Union
Included in:
Union
Defined in:
lib/functional/union.rb

Overview

An immutable data structure with multiple fields, only one of which can be set at any given time. A Union is a convenient way to bundle a number of field attributes together, using accessor methods, without having to write an explicit class.

The Union module generates new AbstractStruct subclasses that hold a set of fields with one and only one value associated with a single field. For each field a reader method is created along with a predicate and a factory. The predicate method indicates whether or not the give field is set. The reader method returns the value of that field or nil when not set. The factory creates a new union with the appropriate field set with the given value.

A Union is very similar to a Ruby Struct and shares many of its behaviors and attributes. Where a Struct can have zero or more values, each of which is assiciated with a field, a Union can have one and only one value. Unlike a Ruby Struct, a Union is immutable: its value is set at construction and it can never be changed. Divergence between the two classes derive from these two core differences.

Examples:

Creating a New Class


LeftRightCenter = Functional::Union.new(:left, :right, :center) #=> LeftRightCenter
LeftRightCenter.ancestors #=> [LeftRightCenter, Functional::AbstractStruct... ]
LeftRightCenter.fields   #=> [:left, :right, :center]

prize = LeftRightCenter.right('One million dollars!') #=> #<union LeftRightCenter... >
prize.fields #=> [:left, :right, :center]
prize.values  #=> [nil, "One million dollars!", nil]

prize.left?   #=> false
prize.right?  #=> true
prize.center? #=> false

prize.left    #=> nil
prize.right   #=> "One million dollars!"
prize.center  #=> nil

Registering a New Class with Union


Functional::Union.new('Suit', :clubs, :diamonds, :hearts, :spades)
 #=> Functional::Union::Suit

Functional::Union::Suit.hearts('Queen')
 #=> #<union Functional::Union::Suit :clubs=>nil, :diamonds=>nil, :hearts=>"Queen", :spades=>nil>

See Also:

Since:

  • 1.0.0

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.new(*fields) ⇒ Functional::AbstractStruct

Create a new union class with the given fields.

Returns:

Raises:

  • (ArgumentError)

    no fields specified

Since:

  • 1.0.0



65
66
67
68
# File 'lib/functional/union.rb', line 65

def new(*fields)
  raise ArgumentError.new('no fields provided') if fields.empty?
  build(fields)
end

Instance Method Details

#new(*fields) ⇒ Functional::AbstractStruct

Create a new union class with the given fields.

Returns:

Raises:

  • (ArgumentError)

    no fields specified

Since:

  • 1.0.0



65
66
67
68
# File 'lib/functional/union.rb', line 65

def new(*fields)
  raise ArgumentError.new('no fields provided') if fields.empty?
  build(fields)
end