@@ -18,7 +18,40 @@ module Concurrent
18
18
# new value to the result of running the given block if and only if that
19
19
# value validates.
20
20
#
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.
22
55
#
23
56
# @see http://clojure.org/atoms Clojure Atoms
24
57
class Atom < Synchronization ::Object
@@ -33,7 +66,14 @@ class Atom < Synchronization::Object
33
66
# intended new value. The validator will return true if the new value
34
67
# is acceptable else return false (preferrably) or raise an exception.
35
68
#
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.
37
77
#
38
78
# @raise [ArgumentError] if the validator is not a `Proc` (when given)
39
79
def initialize ( value , opts = { } )
0 commit comments