@@ -18,7 +18,40 @@ module Concurrent
1818 # new value to the result of running the given block if and only if that
1919 # value validates.
2020 #
21- # @!macro copy_options
21+ # @!macro [attach] copy_options
22+ # ## Copy Options
23+ #
24+ # Object references in Ruby are mutable. This can lead to serious
25+ # problems when the {#value} of an object is a mutable reference. Which
26+ # is always the case unless the value is a `Fixnum`, `Symbol`, or similar
27+ # "primative" data type. Each instance can be configured with a few
28+ # options that can help protect the program from potentially dangerous
29+ # operations. Each of these options can be optionally set when the oject
30+ # instance is created:
31+ #
32+ # * `:dup_on_deref` When true the object will call the `#dup` method on
33+ # the `value` object every time the `#value` methid is called
34+ # (default: false)
35+ # * `:freeze_on_deref` When true the object will call the `#freeze`
36+ # method on the `value` object every time the `#value` method is called
37+ # (default: false)
38+ # * `:copy_on_deref` When given a `Proc` object the `Proc` will be run
39+ # every time the `#value` method is called. The `Proc` will be given
40+ # the current `value` as its only argument and the result returned by
41+ # the block will be the return value of the `#value` call. When `nil`
42+ # this option will be ignored (default: nil)
43+ #
44+ # When multiple deref options are set the order of operations is strictly defined.
45+ # The order of deref operations is:
46+ # * `:copy_on_deref`
47+ # * `:dup_on_deref`
48+ # * `:freeze_on_deref`
49+ #
50+ # Because of this ordering there is no need to `#freeze` an object created by a
51+ # provided `:copy_on_deref` block. Simply set `:freeze_on_deref` to `true`.
52+ # Setting both `:dup_on_deref` to `true` and `:freeze_on_deref` to `true` is
53+ # as close to the behavior of a "pure" functional language (like Erlang, Clojure,
54+ # or Haskell) as we are likely to get in Ruby.
2255 #
2356 # @see http://clojure.org/atoms Clojure Atoms
2457 class Atom < Synchronization ::Object
@@ -33,7 +66,14 @@ class Atom < Synchronization::Object
3366 # intended new value. The validator will return true if the new value
3467 # is acceptable else return false (preferrably) or raise an exception.
3568 #
36- # @!macro deref_options
69+ # @!macro [attach] deref_options
70+ # @option opts [Boolean] :dup_on_deref (false) Call `#dup` before
71+ # returning the data from {#value}
72+ # @option opts [Boolean] :freeze_on_deref (false) Call `#freeze` before
73+ # returning the data from {#value}
74+ # @option opts [Proc] :copy_on_deref (nil) When calling the {#value}
75+ # method, call the given proc passing the internal value as the sole
76+ # argument then return the new value returned from the proc.
3777 #
3878 # @raise [ArgumentError] if the validator is not a `Proc` (when given)
3979 def initialize ( value , opts = { } )
0 commit comments