concurrent-ruby 1.0.5 → 1.1.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +42 -0
  3. data/Gemfile +39 -0
  4. data/{LICENSE.txt → LICENSE.md} +2 -0
  5. data/README.md +203 -105
  6. data/Rakefile +278 -0
  7. data/ext/concurrent-ruby/ConcurrentRubyService.java +17 -0
  8. data/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +175 -0
  9. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java +248 -0
  10. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java +93 -0
  11. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java +113 -0
  12. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java +159 -0
  13. data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +304 -0
  14. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java +31 -0
  15. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java +3863 -0
  16. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java +203 -0
  17. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java +342 -0
  18. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java +3800 -0
  19. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java +204 -0
  20. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java +291 -0
  21. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java +199 -0
  22. data/lib/concurrent-ruby.rb +1 -0
  23. data/lib/concurrent.rb +24 -20
  24. data/lib/concurrent/agent.rb +7 -7
  25. data/lib/concurrent/array.rb +59 -32
  26. data/lib/concurrent/async.rb +4 -4
  27. data/lib/concurrent/atom.rb +9 -9
  28. data/lib/concurrent/atomic/atomic_boolean.rb +24 -20
  29. data/lib/concurrent/atomic/atomic_fixnum.rb +27 -23
  30. data/lib/concurrent/atomic/atomic_markable_reference.rb +164 -0
  31. data/lib/concurrent/atomic/atomic_reference.rb +176 -33
  32. data/lib/concurrent/atomic/count_down_latch.rb +6 -6
  33. data/lib/concurrent/atomic/cyclic_barrier.rb +1 -1
  34. data/lib/concurrent/atomic/event.rb +1 -1
  35. data/lib/concurrent/atomic/java_count_down_latch.rb +6 -5
  36. data/lib/concurrent/atomic/mutex_count_down_latch.rb +1 -0
  37. data/lib/concurrent/atomic/read_write_lock.rb +2 -1
  38. data/lib/concurrent/atomic/reentrant_read_write_lock.rb +3 -1
  39. data/lib/concurrent/atomic/semaphore.rb +8 -8
  40. data/lib/concurrent/atomic/thread_local_var.rb +7 -7
  41. data/lib/concurrent/atomic_reference/mutex_atomic.rb +3 -8
  42. data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +1 -1
  43. data/lib/concurrent/atomics.rb +0 -43
  44. data/lib/concurrent/collection/lock_free_stack.rb +127 -0
  45. data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +3 -3
  46. data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +1 -2
  47. data/lib/concurrent/collection/non_concurrent_priority_queue.rb +29 -29
  48. data/lib/concurrent/concern/dereferenceable.rb +1 -1
  49. data/lib/concurrent/concern/logging.rb +6 -1
  50. data/lib/concurrent/concern/observable.rb +7 -7
  51. data/lib/concurrent/concurrent_ruby.jar +0 -0
  52. data/lib/concurrent/configuration.rb +1 -6
  53. data/lib/concurrent/constants.rb +1 -1
  54. data/lib/concurrent/dataflow.rb +2 -1
  55. data/lib/concurrent/delay.rb +9 -7
  56. data/lib/concurrent/exchanger.rb +13 -21
  57. data/lib/concurrent/executor/abstract_executor_service.rb +2 -2
  58. data/lib/concurrent/executor/cached_thread_pool.rb +1 -1
  59. data/lib/concurrent/executor/executor_service.rb +15 -15
  60. data/lib/concurrent/executor/fixed_thread_pool.rb +18 -18
  61. data/lib/concurrent/executor/java_thread_pool_executor.rb +10 -7
  62. data/lib/concurrent/executor/single_thread_executor.rb +2 -2
  63. data/lib/concurrent/executor/thread_pool_executor.rb +6 -6
  64. data/lib/concurrent/executor/timer_set.rb +1 -1
  65. data/lib/concurrent/future.rb +4 -1
  66. data/lib/concurrent/hash.rb +53 -30
  67. data/lib/concurrent/ivar.rb +5 -6
  68. data/lib/concurrent/map.rb +20 -25
  69. data/lib/concurrent/maybe.rb +1 -1
  70. data/lib/concurrent/mutable_struct.rb +15 -14
  71. data/lib/concurrent/mvar.rb +2 -2
  72. data/lib/concurrent/promise.rb +53 -21
  73. data/lib/concurrent/promises.rb +1938 -0
  74. data/lib/concurrent/re_include.rb +58 -0
  75. data/lib/concurrent/set.rb +66 -0
  76. data/lib/concurrent/settable_struct.rb +1 -0
  77. data/lib/concurrent/synchronization.rb +4 -5
  78. data/lib/concurrent/synchronization/abstract_lockable_object.rb +5 -5
  79. data/lib/concurrent/synchronization/abstract_struct.rb +6 -4
  80. data/lib/concurrent/synchronization/lockable_object.rb +6 -6
  81. data/lib/concurrent/synchronization/{mri_lockable_object.rb → mutex_lockable_object.rb} +19 -14
  82. data/lib/concurrent/synchronization/object.rb +8 -4
  83. data/lib/concurrent/synchronization/truffleruby_object.rb +46 -0
  84. data/lib/concurrent/synchronization/volatile.rb +11 -9
  85. data/lib/concurrent/thread_safe/util/data_structures.rb +55 -0
  86. data/lib/concurrent/thread_safe/util/striped64.rb +9 -4
  87. data/lib/concurrent/timer_task.rb +5 -2
  88. data/lib/concurrent/tuple.rb +1 -1
  89. data/lib/concurrent/tvar.rb +2 -2
  90. data/lib/concurrent/utility/at_exit.rb +1 -1
  91. data/lib/concurrent/utility/engine.rb +2 -2
  92. data/lib/concurrent/utility/monotonic_time.rb +3 -3
  93. data/lib/concurrent/utility/native_extension_loader.rb +31 -33
  94. data/lib/concurrent/utility/processor_counter.rb +0 -2
  95. data/lib/concurrent/version.rb +2 -2
  96. metadata +35 -21
  97. data/lib/concurrent/atomic_reference/concurrent_update_error.rb +0 -8
  98. data/lib/concurrent/atomic_reference/direct_update.rb +0 -81
  99. data/lib/concurrent/atomic_reference/jruby+truffle.rb +0 -2
  100. data/lib/concurrent/atomic_reference/jruby.rb +0 -16
  101. data/lib/concurrent/atomic_reference/rbx.rb +0 -22
  102. data/lib/concurrent/atomic_reference/ruby.rb +0 -32
  103. data/lib/concurrent/edge.rb +0 -26
  104. data/lib/concurrent/lazy_register.rb +0 -81
  105. data/lib/concurrent/synchronization/truffle_lockable_object.rb +0 -9
  106. data/lib/concurrent/synchronization/truffle_object.rb +0 -31
  107. data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +0 -30
@@ -90,10 +90,10 @@ if Concurrent.on_jruby?
90
90
  private
91
91
 
92
92
  def ns_initialize(opts)
93
- min_length = opts.fetch(:min_threads, DEFAULT_MIN_POOL_SIZE).to_i
94
- max_length = opts.fetch(:max_threads, DEFAULT_MAX_POOL_SIZE).to_i
95
- idletime = opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT).to_i
96
- @max_queue = opts.fetch(:max_queue, DEFAULT_MAX_QUEUE_SIZE).to_i
93
+ min_length = opts.fetch(:min_threads, DEFAULT_MIN_POOL_SIZE).to_i
94
+ max_length = opts.fetch(:max_threads, DEFAULT_MAX_POOL_SIZE).to_i
95
+ idletime = opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT).to_i
96
+ @max_queue = opts.fetch(:max_queue, DEFAULT_MAX_QUEUE_SIZE).to_i
97
97
  @fallback_policy = opts.fetch(:fallback_policy, :abort)
98
98
 
99
99
  raise ArgumentError.new("`max_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if max_length < DEFAULT_MIN_POOL_SIZE
@@ -109,9 +109,12 @@ if Concurrent.on_jruby?
109
109
  end
110
110
 
111
111
  @executor = java.util.concurrent.ThreadPoolExecutor.new(
112
- min_length, max_length,
113
- idletime, java.util.concurrent.TimeUnit::SECONDS,
114
- queue, FALLBACK_POLICY_CLASSES[@fallback_policy].new)
112
+ min_length,
113
+ max_length,
114
+ idletime,
115
+ java.util.concurrent.TimeUnit::SECONDS,
116
+ queue,
117
+ FALLBACK_POLICY_CLASSES[@fallback_policy].new)
115
118
 
116
119
  self.auto_terminate = opts.fetch(:auto_terminate, true)
117
120
  end
@@ -14,7 +14,7 @@ module Concurrent
14
14
  end
15
15
  private_constant :SingleThreadExecutorImplementation
16
16
 
17
- # @!macro [attach] single_thread_executor
17
+ # @!macro single_thread_executor
18
18
  #
19
19
  # A thread pool with a single thread an unlimited queue. Should the thread
20
20
  # die for any reason it will be removed and replaced, thus ensuring that
@@ -35,7 +35,7 @@ module Concurrent
35
35
  # @!macro abstract_executor_service_public_api
36
36
  class SingleThreadExecutor < SingleThreadExecutorImplementation
37
37
 
38
- # @!macro [new] single_thread_executor_method_initialize
38
+ # @!macro single_thread_executor_method_initialize
39
39
  #
40
40
  # Create a new thread pool.
41
41
  #
@@ -15,7 +15,7 @@ module Concurrent
15
15
  end
16
16
  private_constant :ThreadPoolExecutorImplementation
17
17
 
18
- # @!macro [attach] thread_pool_executor
18
+ # @!macro thread_pool_executor
19
19
  #
20
20
  # An abstraction composed of one or more threads and a task queue. Tasks
21
21
  # (blocks or `proc` objects) are submitted to the pool and added to the queue.
@@ -55,12 +55,12 @@ module Concurrent
55
55
  # @!macro thread_pool_executor_public_api
56
56
  class ThreadPoolExecutor < ThreadPoolExecutorImplementation
57
57
 
58
- # @!macro [new] thread_pool_executor_method_initialize
58
+ # @!macro thread_pool_executor_method_initialize
59
59
  #
60
60
  # Create a new thread pool.
61
- #
61
+ #
62
62
  # @param [Hash] opts the options which configure the thread pool.
63
- #
63
+ #
64
64
  # @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
65
65
  # number of threads to be created
66
66
  # @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted
@@ -73,12 +73,12 @@ module Concurrent
73
73
  # @option opts [Symbol] :fallback_policy (:abort) the policy for handling new
74
74
  # tasks that are received when the queue size has reached
75
75
  # `max_queue` or the executor has shut down
76
- #
76
+ #
77
77
  # @raise [ArgumentError] if `:max_threads` is less than one
78
78
  # @raise [ArgumentError] if `:min_threads` is less than zero
79
79
  # @raise [ArgumentError] if `:fallback_policy` is not one of the values specified
80
80
  # in `FALLBACK_POLICIES`
81
- #
81
+ #
82
82
  # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
83
83
 
84
84
  # @!method initialize(opts = {})
@@ -20,7 +20,7 @@ module Concurrent
20
20
 
21
21
  # Create a new set of timed tasks.
22
22
  #
23
- # @!macro [attach] executor_options
23
+ # @!macro executor_options
24
24
  #
25
25
  # @param [Hash] opts the options used to specify the executor on which to perform actions
26
26
  # @option opts [Executor] :executor when set use the given `Executor` instance.
@@ -6,9 +6,12 @@ require 'concurrent/executor/safe_task_executor'
6
6
 
7
7
  require 'concurrent/options'
8
8
 
9
+ # TODO (pitr-ch 14-Mar-2017): deprecate, Future, Promise, etc.
10
+
11
+
9
12
  module Concurrent
10
13
 
11
- # {include:file:doc/future.md}
14
+ # {include:file:docs-source/future.md}
12
15
  #
13
16
  # @!macro copy_options
14
17
  #
@@ -2,35 +2,58 @@ require 'concurrent/utility/engine'
2
2
  require 'concurrent/thread_safe/util'
3
3
 
4
4
  module Concurrent
5
- if Concurrent.on_cruby?
6
-
7
- # @!macro [attach] concurrent_hash
8
- #
9
- # A thread-safe subclass of Hash. This version locks against the object
10
- # itself for every method call, ensuring only one thread can be reading
11
- # or writing at a time. This includes iteration methods like `#each`,
12
- # which takes the lock repeatedly when reading an item.
13
- #
14
- # @see http://ruby-doc.org/core-2.2.0/Hash.html Ruby standard library `Hash`
15
- class Hash < ::Hash;
16
- end
17
-
18
- elsif Concurrent.on_jruby?
19
- require 'jruby/synchronized'
20
-
21
- # @!macro concurrent_hash
22
- class Hash < ::Hash
23
- include JRuby::Synchronized
24
- end
25
-
26
- elsif Concurrent.on_rbx? || Concurrent.on_truffle?
27
- require 'monitor'
28
- require 'concurrent/thread_safe/util/array_hash_rbx'
29
-
30
- # @!macro concurrent_hash
31
- class Hash < ::Hash
32
- end
33
-
34
- ThreadSafe::Util.make_synchronized_on_rbx Hash
5
+
6
+ # @!macro concurrent_hash
7
+ #
8
+ # A thread-safe subclass of Hash. This version locks against the object
9
+ # itself for every method call, ensuring only one thread can be reading
10
+ # or writing at a time. This includes iteration methods like `#each`,
11
+ # which takes the lock repeatedly when reading an item.
12
+ #
13
+ # @see http://ruby-doc.org/core-2.2.0/Hash.html Ruby standard library `Hash`
14
+
15
+ # @!macro internal_implementation_note
16
+ HashImplementation = case
17
+ when Concurrent.on_cruby?
18
+ # Because MRI never runs code in parallel, the existing
19
+ # non-thread-safe structures should usually work fine.
20
+ ::Hash
21
+
22
+ when Concurrent.on_jruby?
23
+ require 'jruby/synchronized'
24
+
25
+ class JRubyHash < ::Hash
26
+ include JRuby::Synchronized
27
+ end
28
+ JRubyHash
29
+
30
+ when Concurrent.on_rbx?
31
+ require 'monitor'
32
+ require 'concurrent/thread_safe/util/data_structures'
33
+
34
+ class RbxHash < ::Hash
35
+ end
36
+ ThreadSafe::Util.make_synchronized_on_rbx RbxHash
37
+ RbxHash
38
+
39
+ when Concurrent.on_truffleruby?
40
+ require 'concurrent/thread_safe/util/data_structures'
41
+
42
+ class TruffleRubyHash < ::Hash
43
+ end
44
+
45
+ ThreadSafe::Util.make_synchronized_on_truffleruby TruffleRubyHash
46
+ TruffleRubyHash
47
+
48
+ else
49
+ warn 'Possibly unsupported Ruby implementation'
50
+ ::Hash
51
+ end
52
+ private_constant :HashImplementation
53
+
54
+ # @!macro concurrent_hash
55
+ class Hash < HashImplementation
35
56
  end
57
+
36
58
  end
59
+
@@ -98,10 +98,10 @@ module Concurrent
98
98
  observer
99
99
  end
100
100
 
101
- # @!macro [attach] ivar_set_method
101
+ # @!macro ivar_set_method
102
102
  # Set the `IVar` to a value and wake or notify all threads waiting on it.
103
103
  #
104
- # @!macro [attach] ivar_set_parameters_and_exceptions
104
+ # @!macro ivar_set_parameters_and_exceptions
105
105
  # @param [Object] value the value to store in the `IVar`
106
106
  # @yield A block operation to use for setting the value
107
107
  # @raise [ArgumentError] if both a value and a block are given
@@ -124,7 +124,7 @@ module Concurrent
124
124
  self
125
125
  end
126
126
 
127
- # @!macro [attach] ivar_fail_method
127
+ # @!macro ivar_fail_method
128
128
  # Set the `IVar` to failed due to some error and wake or notify all threads waiting on it.
129
129
  #
130
130
  # @param [Object] reason for the failure
@@ -157,9 +157,8 @@ module Concurrent
157
157
  self.observers = Collection::CopyOnWriteObserverSet.new
158
158
  set_deref_options(opts)
159
159
 
160
- if value == NULL
161
- @state = :pending
162
- else
160
+ @state = :pending
161
+ if value != NULL
163
162
  ns_complete_without_notification(true, value, nil)
164
163
  end
165
164
  end
@@ -1,33 +1,27 @@
1
1
  require 'thread'
2
2
  require 'concurrent/constants'
3
3
  require 'concurrent/synchronization'
4
+ require 'concurrent/utility/engine'
4
5
 
5
6
  module Concurrent
6
7
  # @!visibility private
7
8
  module Collection
8
9
 
9
10
  # @!visibility private
10
- MapImplementation = if Concurrent.java_extensions_loaded?
11
+ MapImplementation = case
12
+ when Concurrent.on_jruby?
11
13
  # noinspection RubyResolve
12
14
  JRubyMapBackend
13
- elsif defined?(RUBY_ENGINE)
14
- case RUBY_ENGINE
15
- when 'ruby'
16
- require 'concurrent/collection/map/mri_map_backend'
17
- MriMapBackend
18
- when 'rbx'
19
- require 'concurrent/collection/map/atomic_reference_map_backend'
20
- AtomicReferenceMapBackend
21
- when 'jruby+truffle'
22
- require 'concurrent/collection/map/atomic_reference_map_backend'
23
- AtomicReferenceMapBackend
24
- else
25
- warn 'Concurrent::Map: unsupported Ruby engine, using a fully synchronized Concurrent::Map implementation' if $VERBOSE
26
- require 'concurrent/collection/map/synchronized_map_backend'
27
- SynchronizedMapBackend
28
- end
29
- else
15
+ when Concurrent.on_cruby?
16
+ require 'concurrent/collection/map/mri_map_backend'
30
17
  MriMapBackend
18
+ when Concurrent.on_rbx? || Concurrent.on_truffleruby?
19
+ require 'concurrent/collection/map/atomic_reference_map_backend'
20
+ AtomicReferenceMapBackend
21
+ else
22
+ warn 'Concurrent::Map: unsupported Ruby engine, using a fully synchronized Concurrent::Map implementation'
23
+ require 'concurrent/collection/map/synchronized_map_backend'
24
+ SynchronizedMapBackend
31
25
  end
32
26
  end
33
27
 
@@ -43,7 +37,7 @@ module Concurrent
43
37
  # > map = Concurrent::Map.new
44
38
  class Map < Collection::MapImplementation
45
39
 
46
- # @!macro [new] map_method_is_atomic
40
+ # @!macro map_method_is_atomic
47
41
  # This method is atomic. Atomic methods of `Map` which accept a block
48
42
  # do not allow the `self` instance to be used within the block. Doing
49
43
  # so will cause a deadlock.
@@ -106,7 +100,7 @@ module Concurrent
106
100
  alias_method :get, :[]
107
101
  alias_method :put, :[]=
108
102
 
109
- # @!macro [attach] map_method_not_atomic
103
+ # @!macro map_method_not_atomic
110
104
  # The "fetch-then-act" methods of `Map` are not atomic. `Map` is intended
111
105
  # to be use as a concurrency primitive with strong happens-before
112
106
  # guarantees. It is not intended to be used as a high-level abstraction
@@ -171,6 +165,11 @@ module Concurrent
171
165
  each_pair {|k, v| yield v}
172
166
  end unless method_defined?(:each_value)
173
167
 
168
+ def each_pair
169
+ return enum_for :each_pair unless block_given?
170
+ super
171
+ end
172
+
174
173
  alias_method :each, :each_pair unless method_defined?(:each)
175
174
 
176
175
  def key(value)
@@ -205,12 +204,8 @@ module Concurrent
205
204
  undef :freeze
206
205
 
207
206
  # @!visibility private
208
- DEFAULT_OBJ_ID_STR_WIDTH = 0.size == 4 ? 7 : 14 # we want to look "native", 7 for 32-bit, 14 for 64-bit
209
- # override default #inspect() method: firstly, we don't want to be spilling our guts (i-vars), secondly, MRI backend's
210
- # #inspect() call on its @backend i-var will bump @backend's iter level while possibly yielding GVL
211
207
  def inspect
212
- id_str = (object_id << 1).to_s(16).rjust(DEFAULT_OBJ_ID_STR_WIDTH, '0')
213
- "#<#{self.class.name}:0x#{id_str} entries=#{size} default_proc=#{@default_proc.inspect}>"
208
+ format '%s entries=%d default_proc=%s>', to_s[0..-2], size.to_s, @default_proc.inspect
214
209
  end
215
210
 
216
211
  private
@@ -108,7 +108,7 @@ module Concurrent
108
108
  # Indicates that the given attribute has not been set.
109
109
  # When `Just` the {#nothing} getter will return `NONE`.
110
110
  # When `Nothing` the {#just} getter will return `NONE`.
111
- NONE = Object.new.freeze
111
+ NONE = ::Object.new.freeze
112
112
 
113
113
  # The value of a `Maybe` when `Just`. Will be `NONE` when `Nothing`.
114
114
  attr_reader :just
@@ -10,7 +10,7 @@ module Concurrent
10
10
  module MutableStruct
11
11
  include Synchronization::AbstractStruct
12
12
 
13
- # @!macro [new] struct_new
13
+ # @!macro struct_new
14
14
  #
15
15
  # Factory for creating new struct classes.
16
16
  #
@@ -42,7 +42,7 @@ module Concurrent
42
42
  #
43
43
  # @see http://ruby-doc.org/core-2.2.0/Struct.html#method-c-new Ruby standard library `Struct#new`
44
44
 
45
- # @!macro [attach] struct_values
45
+ # @!macro struct_values
46
46
  #
47
47
  # Returns the values for this struct as an Array.
48
48
  #
@@ -53,7 +53,7 @@ module Concurrent
53
53
  end
54
54
  alias_method :to_a, :values
55
55
 
56
- # @!macro [attach] struct_values_at
56
+ # @!macro struct_values_at
57
57
  #
58
58
  # Returns the struct member values for each selector as an Array.
59
59
  #
@@ -64,7 +64,7 @@ module Concurrent
64
64
  synchronize { ns_values_at(indexes) }
65
65
  end
66
66
 
67
- # @!macro [attach] struct_inspect
67
+ # @!macro struct_inspect
68
68
  #
69
69
  # Describe the contents of this struct in a string.
70
70
  #
@@ -74,7 +74,7 @@ module Concurrent
74
74
  end
75
75
  alias_method :to_s, :inspect
76
76
 
77
- # @!macro [attach] struct_merge
77
+ # @!macro struct_merge
78
78
  #
79
79
  # Returns a new struct containing the contents of `other` and the contents
80
80
  # of `self`. If no block is specified, the value for entries with duplicate
@@ -95,7 +95,7 @@ module Concurrent
95
95
  synchronize { ns_merge(other, &block) }
96
96
  end
97
97
 
98
- # @!macro [attach] struct_to_h
98
+ # @!macro struct_to_h
99
99
  #
100
100
  # Returns a hash containing the names and values for the struct’s members.
101
101
  #
@@ -104,11 +104,11 @@ module Concurrent
104
104
  synchronize { ns_to_h }
105
105
  end
106
106
 
107
- # @!macro [attach] struct_get
107
+ # @!macro struct_get
108
108
  #
109
109
  # Attribute Reference
110
110
  #
111
- # @param [Symbol, String, Integer] member the string or symbol name of the memeber
111
+ # @param [Symbol, String, Integer] member the string or symbol name of the member
112
112
  # for which to obtain the value or the member's index
113
113
  #
114
114
  # @return [Object] the value of the given struct member or the member at the given index.
@@ -119,7 +119,7 @@ module Concurrent
119
119
  synchronize { ns_get(member) }
120
120
  end
121
121
 
122
- # @!macro [attach] struct_equality
122
+ # @!macro struct_equality
123
123
  #
124
124
  # Equality
125
125
  #
@@ -129,7 +129,7 @@ module Concurrent
129
129
  synchronize { ns_equality(other) }
130
130
  end
131
131
 
132
- # @!macro [attach] struct_each
132
+ # @!macro struct_each
133
133
  #
134
134
  # Yields the value of each struct member in order. If no block is given
135
135
  # an enumerator is returned.
@@ -141,7 +141,7 @@ module Concurrent
141
141
  synchronize { ns_each(&block) }
142
142
  end
143
143
 
144
- # @!macro [attach] struct_each_pair
144
+ # @!macro struct_each_pair
145
145
  #
146
146
  # Yields the name and value of each struct member in order. If no block is
147
147
  # given an enumerator is returned.
@@ -154,7 +154,7 @@ module Concurrent
154
154
  synchronize { ns_each_pair(&block) }
155
155
  end
156
156
 
157
- # @!macro [attach] struct_select
157
+ # @!macro struct_select
158
158
  #
159
159
  # Yields each member value from the struct to the block and returns an Array
160
160
  # containing the member values from the struct for which the given block
@@ -169,13 +169,13 @@ module Concurrent
169
169
  synchronize { ns_select(&block) }
170
170
  end
171
171
 
172
- # @!macro [new] struct_set
172
+ # @!macro struct_set
173
173
  #
174
174
  # Attribute Assignment
175
175
  #
176
176
  # Sets the value of the given struct member or the member at the given index.
177
177
  #
178
- # @param [Symbol, String, Integer] member the string or symbol name of the memeber
178
+ # @param [Symbol, String, Integer] member the string or symbol name of the member
179
179
  # for which to obtain the value or the member's index
180
180
  #
181
181
  # @return [Object] the value of the given struct member or the member at the given index.
@@ -212,6 +212,7 @@ module Concurrent
212
212
  synchronize do
213
213
  clazz = Synchronization::AbstractStruct.define_struct_class(MutableStruct, Synchronization::LockableObject, name, members, &block)
214
214
  members.each_with_index do |member, index|
215
+ clazz.send :remove_method, member
215
216
  clazz.send(:define_method, member) do
216
217
  synchronize { @values[index] }
217
218
  end