core-state 0.1.0 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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.