Class: Functional::FinalVar

Inherits:
Synchronization::Object
  • Object
show all
Defined in:
lib/functional/final_var.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.

A thread safe object that holds a single value and is "final" (meaning that the value can be set at most once after which it becomes immutable). The value can be set at instantiation which will result in the object becoming fully and immediately immutable. Attempting to set the value once it has been set is a logical error and will result in an exception being raised.

Examples:

Instanciation With No Value

f = Functional::FinalVar.new
  #=> #<Functional::FinalVar unset>
f.set?       #=> false
f.value      #=> nil
f.value = 42 #=> 42
f.inspect
  #=> "#<Functional::FinalVar value=42>"
f.set?       #=> true
f.value      #=> 42

Instanciation With an Initial Value

f = Functional::FinalVar.new(42)
  #=> #<Functional::FinalVar value=42>
f.set?       #=> true
f.value      #=> 42

See Also:

Instance Method Summary collapse

Constructor Details

#initialize(value = NO_VALUE) ⇒ FinalVar

Create a new FinalVar with the given value or "unset" when no value is given.

Parameters:

  • value (Object) (defaults to: NO_VALUE)

    if given, the immutable value of the object



53
54
55
56
# File 'lib/functional/final_var.rb', line 53

def initialize(value = NO_VALUE)
  super
  synchronize{ @value = value }
end

Instance Method Details

#eql?(other) ⇒ Boolean Also known as: ==

Compares this object and other for equality. A FinalVar that is unset is never equal to anything else (it represents a complete absence of value). When set a FinalVar is equal to another FinalVar if they have the same value. A FinalVar is equal to another object if its value is equal to the other object using Ruby's normal equality rules.

Parameters:

  • other (Object)

    the object to compare equality to

Returns:

  • (Boolean)

    true if equal else false



120
121
122
123
124
125
126
127
128
# File 'lib/functional/final_var.rb', line 120

def eql?(other)
  if (val = fetch(NO_VALUE)) == NO_VALUE
    false
  elsif other.is_a?(FinalVar)
    val == other.value
  else
    val == other
  end
end

#fetch(default) ⇒ Object

Get the value if set else return the given default value.

Parameters:

  • default (Object)

    the value to return if currently unset

Returns:

  • (Object)

    the current value when set else the given default



108
109
110
# File 'lib/functional/final_var.rb', line 108

def fetch(default)
  synchronize { has_been_set? ? @value : default }
end

#getObject Also known as: value

Get the current value or nil if unset.

Returns:

  • (Object)

    the current value or nil



61
62
63
# File 'lib/functional/final_var.rb', line 61

def get
  synchronize { has_been_set? ? @value : nil }
end

#get_or_set(value) ⇒ Object

Get the value if it has been set else set the value.

Parameters:

  • value (Object)

    the value to set

Returns:

  • (Object)

    the current value if already set else the new value



94
95
96
97
98
99
100
101
102
# File 'lib/functional/final_var.rb', line 94

def get_or_set(value)
  synchronize do
    if has_been_set?
      @value
    else
      @value = value
    end
  end
end

#set(value) ⇒ Object Also known as: value=

Set the value. Will raise an exception if already set.

Parameters:

  • value (Object)

    the value to set

Returns:

  • (Object)

    the new value

Raises:



71
72
73
74
75
76
77
78
79
# File 'lib/functional/final_var.rb', line 71

def set(value)
  synchronize do
    if has_been_set?
      raise FinalityError.new('value has already been set')
    else
      @value = value
    end
  end
end

#set?Boolean Also known as: value?

Has the value been set?

Returns:

  • (Boolean)

    true when the value has been set else false



85
86
87
# File 'lib/functional/final_var.rb', line 85

def set?
  synchronize { has_been_set? }
end