core-state 0.1.0 → 0.1.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a830666ebf18447a8c3274d2952173dc3533af6b0321b95e785b3008c58d6ab8
4
- data.tar.gz: f3bd2ec548d47fa6fc9c66fa0dca8f6d1d9ecd721916a3de935827aab6a48805
3
+ metadata.gz: 7c21289439e5a70015dc1fad5f146ce0742296965b142b7e1a358195a4eeae7e
4
+ data.tar.gz: c02f0889fd523fcb34c865b2dd3232a2bd2bce51c0211bff5f21c14aef848daa
5
5
  SHA512:
6
- metadata.gz: ba61451ed0cc6974c3b2808dfcbd72aa693be05630e77896ac3921deec4c9d3481a5cab7213bc33cf923449bd254babd875458bf3f9940e4c1433ec8ee82048a
7
- data.tar.gz: 0654f08454d2d04e2daca056c08964fc4fc644b70e854208f7cb24e24f00fdb117e37e35856f333692a12653e8fc16d40525c55948de49e31d285022e231f1f7
6
+ metadata.gz: 753c19c8d932f869ab172136b3772e70502969ed4c702317c61de491d2fe52da8b6a6b32a1e5b00b02535e0a46bd0f3d33e62b56fa1862c7e6c2c6803fe3da84
7
+ data.tar.gz: f660e4cc842ef45e30b6ee665af5a4a8aa33de9c170e3852afb8bf4c5cd5fd5cf21b028be78927761e1febd2859655a3257d50e9870345469934a9146e94a534
data/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ ## [v0.1.4](https://github.com/metabahn/corerb/releases/tag/2021-09-30)
2
+
3
+ *released on 2021-09-30*
4
+
5
+ * `fix` [#85](https://github.com/metabahn/corerb/pull/85) Initialize with class-level state when available ([bryanp](https://github.com/bryanp))
6
+
7
+ ## [v0.1.3](https://github.com/metabahn/corerb/releases/tag/2021-09-28)
8
+
9
+ *released on 2021-09-28*
10
+
11
+ * `fix` [#84](https://github.com/metabahn/corerb/pull/84) Define core-local as a dependency of core-state ([bryanp](https://github.com/bryanp))
12
+
13
+ ## [v0.1.1](https://github.com/metabahn/corerb/releases/tag/2021-07-15)
14
+
15
+ *released on 2021-07-15*
16
+
17
+ * `fix` [#62](https://github.com/metabahn/corerb/pull/62) Correctly isolate class-level state on access ([bryanp](https://github.com/bryanp))
18
+ * `fix` [#55](https://github.com/metabahn/corerb/pull/55) Correctly forward arguments to super initialize ([bryanp](https://github.com/bryanp))
19
+
1
20
  ## [v0.1.0](https://github.com/metabahn/corerb/releases/tag/2021-07-07)
2
21
 
3
22
  *released on 2021-07-07*
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Core
4
4
  module State
5
- VERSION = "0.1.0"
5
+ VERSION = "0.1.4"
6
6
 
7
7
  def self.version
8
8
  VERSION
data/lib/is/stateful.rb CHANGED
@@ -1,24 +1,94 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "core/extension"
4
-
5
- require "refine/object/copy"
4
+ require "core/local"
6
5
 
7
6
  module Is
8
7
  # [public] Makes objects stateful.
9
8
  #
10
9
  module Stateful
10
+ # Adding core-copy as a dependency of core-state creates a recursive dependency, so just bundle it.
11
+ #
12
+ module Copy
13
+ DEFAULT = ::Object.new
14
+
15
+ refine ::Object do
16
+ # [public] Copies the object using `clone`.
17
+ #
18
+ if RbConfig::CONFIG["RUBY_PROGRAM_VERSION"] < "3"
19
+ def copy(freeze: DEFAULT)
20
+ should_freeze = resolve_freeze_argument(freeze)
21
+
22
+ value = clone(freeze: should_freeze)
23
+ value.freeze if should_freeze
24
+ value
25
+ end
26
+ else
27
+ def copy(freeze: DEFAULT)
28
+ clone(freeze: resolve_freeze_argument(freeze))
29
+ end
30
+ end
31
+
32
+ private def resolve_freeze_argument(value)
33
+ case value
34
+ when DEFAULT
35
+ frozen?
36
+ else
37
+ !!value
38
+ end
39
+ end
40
+ end
41
+
42
+ refine Array do
43
+ # [public] Copies the array, along with each value.
44
+ #
45
+ def copy(freeze: DEFAULT)
46
+ unless Stateful.copying?(self)
47
+ Stateful.prevent_recursion(self) do
48
+ array = map { |value|
49
+ value.copy(freeze: freeze)
50
+ }
51
+
52
+ array.freeze if resolve_freeze_argument(freeze)
53
+
54
+ array
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ refine Hash do
61
+ # [public] Copies the hash, along with each key and value.
62
+ #
63
+ def copy(freeze: DEFAULT)
64
+ unless Stateful.copying?(self)
65
+ Stateful.prevent_recursion(self) do
66
+ hash = {}
67
+
68
+ each_pair do |key, value|
69
+ hash[key.copy(freeze: freeze)] = value.copy(freeze: freeze)
70
+ end
71
+
72
+ hash.freeze if resolve_freeze_argument(freeze)
73
+
74
+ hash
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+
11
81
  extend Is::Extension
12
82
 
13
- using Refine::Object::Copy
83
+ using Copy
14
84
 
15
85
  ALLOWED_FLAGS = %i[class instance].freeze
16
86
 
17
- applied do
87
+ applies do
18
88
  prepend_defined_state_modules
19
89
  end
20
90
 
21
- extends :class do
91
+ extends :definition do
22
92
  # [public] Defines state by name.
23
93
  #
24
94
  # flags - Changes how the state is defined. Possible values include:
@@ -52,6 +122,10 @@ module Is
52
122
  defined_state[ivar_name] = state
53
123
  defined_state_isolations << ivar_name
54
124
 
125
+ if state[:class]
126
+ instance_variable_set(ivar_name, default)
127
+ end
128
+
55
129
  prefix = if private
56
130
  "private "
57
131
  else
@@ -62,9 +136,9 @@ module Is
62
136
  if state[:class]
63
137
  defined_state_class_module.module_eval <<~CODE, __FILE__, __LINE__ + 1
64
138
  #{prefix}def #{method_name}
65
- unless defined_state_isolations.include?(#{ivar_name})
139
+ unless defined_state_isolations.include?(#{ivar_name.inspect})
66
140
  #{ivar_name} = #{ivar_name}.copy
67
- defined_state_isolations << #{ivar_name}
141
+ defined_state_isolations << #{ivar_name.inspect}
68
142
  end
69
143
 
70
144
  #{ivar_name}
@@ -75,9 +149,9 @@ module Is
75
149
  if state[:instance]
76
150
  defined_state_instance_module.module_eval <<~CODE, __FILE__, __LINE__ + 1
77
151
  #{prefix}def #{method_name}
78
- unless defined_state_isolations.include?(#{ivar_name})
152
+ unless defined_state_isolations.include?(#{ivar_name.inspect})
79
153
  #{ivar_name} = #{ivar_name}.copy
80
- defined_state_isolations << #{ivar_name}
154
+ defined_state_isolations << #{ivar_name.inspect}
81
155
  end
82
156
 
83
157
  #{ivar_name}
@@ -167,25 +241,30 @@ module Is
167
241
  end
168
242
  end
169
243
 
170
- extends :instance, prepend: true do
171
- def initialize(*)
172
- self.class.send(:defined_state).each_pair do |name, state|
244
+ extends :implementation, prepend: true do
245
+ def initialize(...)
246
+ self_class = self.class
247
+ self_class.send(:defined_state).each_pair do |name, state|
173
248
  if state[:instance]
174
- instance_variable_set(name, state[:value])
249
+ if state[:class]
250
+ instance_variable_set(name, self_class.instance_variable_get(name))
251
+ else
252
+ instance_variable_set(name, state[:value])
253
+ end
175
254
  end
176
255
  end
177
256
 
178
257
  super
179
258
  end
180
259
 
181
- def initialize_copy(*)
260
+ def initialize_copy(...)
182
261
  @__defined_state_isolations = []
183
262
 
184
263
  super
185
264
  end
186
265
  end
187
266
 
188
- extends :class, :instance do
267
+ extends :definition, :implementation do
189
268
  # [public] Safely mutates state by name, yielding a copy of the current value to the block.
190
269
  #
191
270
  def mutate_state(name, &block)
@@ -196,5 +275,25 @@ module Is
196
275
  @__defined_state_isolations ||= []
197
276
  end
198
277
  end
278
+
279
+ class << self
280
+ include Is::Localized
281
+
282
+ def prevent_recursion(object)
283
+ object_id = object.object_id
284
+ copied_objects[object_id] = true
285
+ yield
286
+ ensure
287
+ copied_objects.delete(object_id)
288
+ end
289
+
290
+ def copying?(object)
291
+ copied_objects[object.object_id]
292
+ end
293
+
294
+ def copied_objects
295
+ localized(:__corerb_copied_objects) || localize(:__corerb_copied_objects, {})
296
+ end
297
+ end
199
298
  end
200
299
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: core-state
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Powell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-07 00:00:00.000000000 Z
11
+ date: 2021-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: core-copy
14
+ name: core-extension
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.0'
19
+ version: '0.3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.0'
26
+ version: '0.3'
27
27
  - !ruby/object:Gem::Dependency
28
- name: core-extension
28
+ name: core-local
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.0'
33
+ version: '0.1'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.0'
40
+ version: '0.1'
41
41
  description: Easily manage object state.
42
42
  email: bryan@metabahn.com
43
43
  executables: []
@@ -68,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
70
  requirements: []
71
- rubygems_version: 3.2.15
71
+ rubygems_version: 3.2.22
72
72
  signing_key:
73
73
  specification_version: 4
74
74
  summary: Easily manage object state.