core-extension 0.3.0 → 0.4.0

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: 02a2bc3087e71c3fc19d9f0c20210833a2a8bd88cf76f6187fade6e389eadf14
4
- data.tar.gz: 8e38b249e3e3e5badcd6f9e6658d967f96f63ab837d563ca5e97f0cc408ee7a8
3
+ metadata.gz: 36cc50171a9abdf4bcc66e06d50de8b882ca63c4e0abcde6e8a0a3c788e18d1b
4
+ data.tar.gz: 1ba5eb71c9c127531de40821d2b6f3edaf4e9f3a3324769cdc0053eb2f3c5c6c
5
5
  SHA512:
6
- metadata.gz: 38f391788aef874938c0e69dd95eaa24fee62737dbd5744a3bfafe0813e52189266ef079808a61d29c93688963b8eef1ef4bad9c38dbe2fcd38fb4ea468a3174
7
- data.tar.gz: a41f51ba2b22432e4cd8505065f3e44fa57d1ba5c38cbc5c7b7fb362698cf47580dca2515b0b35fc0a2d2bd2fa5c498ab7faf1e7a67ada66f5591fb551d32954
6
+ metadata.gz: 60133541a193b46b53e2e727219f4c23ba778bca20e0a7c3d2c3b650b3eca8c4eeaa27510b9b3fbb2e55260543002d63a220b0597308706752eed1994eaa61b6
7
+ data.tar.gz: f64b2074f69a38d694a7de22e6ea42c3cae2cc454f31b5146146031f4b43fcc3626e247c182acbb80b2e7c4bc7fa503eafd9b6928a5231783200d7bedb0fe810
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [v0.4.0](https://github.com/metabahn/corerb/releases/tag/2021-10-24)
2
+
3
+ *released on 2021-10-24*
4
+
5
+ * `add` [#86](https://github.com/metabahn/corerb/pull/86) Copy instance variables when cloning an extension ([bryanp](https://github.com/bryanp))
6
+
1
7
  ## [v0.3.0](https://github.com/metabahn/corerb/releases/tag/2021-07-15)
2
8
 
3
9
  *released on 2021-07-15*
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Core
4
4
  module Extension
5
- VERSION = "0.3.0"
5
+ VERSION = "0.4.0"
6
6
 
7
7
  def self.version
8
8
  VERSION
data/lib/is/extension.rb CHANGED
@@ -7,6 +7,101 @@ module Is
7
7
  # [public] Turn a module into a mixin with superpowers.
8
8
  #
9
9
  module Extension
10
+ # Adding core-copy as a dependency creates a recursive dependency, so just bundle it.
11
+ #
12
+ module Copy
13
+ DEFAULT = ::Object.new
14
+
15
+ refine ::Object do
16
+ if RbConfig::CONFIG["RUBY_PROGRAM_VERSION"] < "3"
17
+ def copy(freeze: DEFAULT)
18
+ should_freeze = resolve_freeze_argument(freeze)
19
+
20
+ value = clone(freeze: should_freeze)
21
+ value.freeze if should_freeze
22
+ value
23
+ end
24
+ else
25
+ def copy(freeze: DEFAULT)
26
+ clone(freeze: resolve_freeze_argument(freeze))
27
+ end
28
+ end
29
+
30
+ private def resolve_freeze_argument(value)
31
+ case value
32
+ when DEFAULT
33
+ frozen?
34
+ else
35
+ !!value
36
+ end
37
+ end
38
+ end
39
+
40
+ refine Array do
41
+ def copy(freeze: DEFAULT)
42
+ unless Extension.copying?(self)
43
+ Extension.prevent_recursion(self) do
44
+ array = map { |value|
45
+ value.copy(freeze: freeze)
46
+ }
47
+
48
+ array.freeze if resolve_freeze_argument(freeze)
49
+
50
+ array
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ refine Hash do
57
+ def copy(freeze: DEFAULT)
58
+ unless Extension.copying?(self)
59
+ Extension.prevent_recursion(self) do
60
+ hash = {}
61
+
62
+ each_pair do |key, value|
63
+ hash[key.copy(freeze: freeze)] = value.copy(freeze: freeze)
64
+ end
65
+
66
+ hash.freeze if resolve_freeze_argument(freeze)
67
+
68
+ hash
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ class << self
76
+ def prevent_recursion(object)
77
+ object_id = object.object_id
78
+ copied_objects[object_id] = true
79
+ yield
80
+ ensure
81
+ copied_objects.delete(object_id)
82
+ end
83
+
84
+ def copying?(object)
85
+ copied_objects[object.object_id]
86
+ end
87
+
88
+ def copied_objects
89
+ # We can't use core-local because it would create a recursive dependency.
90
+ #
91
+ Thread.current["__corerb_localized_#{object_id}__corerb_copied_objects"] ||= {}
92
+ end
93
+ end
94
+
95
+ using Copy
96
+
97
+ def initialize_copy(...)
98
+ super
99
+
100
+ instance_variables.each do |instance_variable|
101
+ instance_variable_set(instance_variable, instance_variable_get(instance_variable).copy)
102
+ end
103
+ end
104
+
10
105
  # [public] Restrict the extension to one or more object types.
11
106
  #
12
107
  def restrict(*types)
@@ -15,11 +110,6 @@ module Is
15
110
 
16
111
  # [public] Define a module to be extended or included into objects that include this extension.
17
112
  #
18
- # TODO: These flags almost need different names, since instance extensions could technically end up on a class.
19
- # Name them by their intended use? Like a definition and usage lifecycle or something.
20
- #
21
- # Maybe `definition` and `implementation`?
22
- #
23
113
  def extends(*flags, dependencies: [], prepend: false, &block)
24
114
  dependencies.each do |dependency|
25
115
  defined_dependencies << Core::Extension::Dependency.new(*flags, dependency: dependency, prepend: prepend)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: core-extension
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
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-15 00:00:00.000000000 Z
11
+ date: 2021-10-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Create mixins with superpowers.
14
14
  email: bryan@metabahn.com
@@ -42,7 +42,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
42
42
  - !ruby/object:Gem::Version
43
43
  version: '0'
44
44
  requirements: []
45
- rubygems_version: 3.2.15
45
+ rubygems_version: 3.2.22
46
46
  signing_key:
47
47
  specification_version: 4
48
48
  summary: Create mixins with superpowers.