Module: Concurrent::Dereferenceable

Included in:
Agent, MVar, Obligation, TimerTask
Defined in:
lib/concurrent/dereferenceable.rb

Overview

Object references in Ruby are mutable. This can lead to serious problems when the #value of a concurrent object is a mutable reference. Which is always the case unless the value is a Fixnum, Symbol, or similar “primitive” data type. Most classes in this library that expose a #value getter method do so using the Dereferenceable mixin module.

Objects with this mixin can be configured with a few options that can help protect the program from potentially dangerous operations.

  • :dup_on_deref when true will call the #dup method on the value object every time the #value method is called (default: false)

  • :freeze_on_deref when true will call the #freeze method on the value object every time the #value method is called (default: false)

  • :copy_on_deref when given a Proc object the Proc will be run every time the #value method is called. The Proc will be given the current value as its only parameter and the result returned by the block will be the return value of the #value call. When nil this option will be ignored (default: nil)

Instance Method Summary collapse

Instance Method Details

#valueObject Also known as: deref

Return the value this object represents after applying the options specified by the #set_deref_options method.

When multiple deref options are set the order of operations is strictly defined. The order of deref operations is:

  • :copy_on_deref

  • :dup_on_deref

  • :freeze_on_deref

Because of this ordering there is no need to #freeze an object created by a provided :copy_on_deref block. Simply set :freeze_on_deref to true. Setting both :dup_on_deref to true and :freeze_on_deref to true is as close to the behavior of a “pure” functional language (like Erlang, Clojure, or Haskell) as we are likely to get in Ruby.

This method is thread-safe and synchronized with the internal #mutex.

Returns:

  • the current value of the object



35
36
37
38
39
40
# File 'lib/concurrent/dereferenceable.rb', line 35

def value
  mutex.lock
  apply_deref_options(@value)
ensure
  mutex.unlock
end