class Functional::FinalVar

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.

@example 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

@example Instanciation With an Initial Value

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

@see Functional::FinalStruct @see en.wikipedia.org/wiki/Final_(Java) Java ‘final` keyword

@!macro [new] thread_safe_final_object

@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.

Constants

NO_VALUE

@!visibility private

Public Class Methods

new(value = NO_VALUE) click to toggle source

Create a new ‘FinalVar` with the given value or “unset” when no value is given.

@param [Object] value if given, the immutable value of the object

Calls superclass method
# File lib/functional/final_var.rb, line 53
def initialize(value = NO_VALUE)
  super
  synchronize{ @value = value }
end

Public Instance Methods

==(other)
Alias for: eql?
eql?(other) click to toggle source

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.

@param [Object] other the object to compare equality to @return [Boolean] true if equal else false

# 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
Also aliased as: ==
fetch(default) click to toggle source

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

@param [Object] default the value to return if currently unset @return [Object] the current value when set else the given default

# File lib/functional/final_var.rb, line 108
def fetch(default)
  synchronize { has_been_set? ? @value : default }
end
get() click to toggle source

Get the current value or nil if unset.

@return [Object] the current value or nil

# File lib/functional/final_var.rb, line 61
def get
  synchronize { has_been_set? ? @value : nil }
end
Also aliased as: value
get_or_set(value) click to toggle source

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

@param [Object] value the value to set @return [Object] the current value if already set else the new value

# 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
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/final_var.rb, line 136
def inspect
  if (val = fetch(NO_VALUE)) == NO_VALUE
    val = 'unset'
  else
    val = "value=#{val.is_a?(String) ? ('"' + val + '"') : val }"
  end
  "#<#{self.class} #{val}>"
end
set(value) click to toggle source

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

@param [Object] value the value to set @return [Object] the new value @raise [Functional::FinalityError] if the value has already been set

# 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
Also aliased as: value=
set?() click to toggle source

Has the value been set?

@return [Boolean] true when the value has been set else false

# File lib/functional/final_var.rb, line 85
def set?
  synchronize { has_been_set? }
end
Also aliased as: value?
to_s() 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/final_var.rb, line 150
def to_s
  value.to_s
end
value()
Alias for: get
value=(value)
Alias for: set
value?()
Alias for: set?

Private Instance Methods

has_been_set?() click to toggle source

Checks the set status without locking the mutex. @return [Boolean] true when set else false

# File lib/functional/final_var.rb, line 158
def has_been_set?
  @value != NO_VALUE
end