moxml 0.5.23 → 0.5.24

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: 4c88f88d6ab8eafea4b11c8007e7b667e1413bfc60715142ef280af00c1909de
4
- data.tar.gz: 8302e755e10fa582f9349c443fc91ed63ddd684ce24c45f0baedd88f0541c16f
3
+ metadata.gz: b1181803fec34397cfd858d8671e2dcd6a02a88418dc5848a5ea9c7a44d7bc64
4
+ data.tar.gz: b9809e6ed48ae4a5a946ed9487fe61d0a89d333b51921de70b50dd271956ba0a
5
5
  SHA512:
6
- metadata.gz: b7067b38f81a13bd29e1c542f66bd99636f594f91a754997744419549e259c0267a69daea3ab147410e425f243e9ddc807441860df8d91f00644b93f5608fd2e
7
- data.tar.gz: 662df0f63b4600b923eeedf4747b04bbd71a3a0cd732d25f2ca4fccaf6b563b710f09d8fd470497434962aa024c1e9354f718ebd8b793649a4aa06033149852b
6
+ metadata.gz: 26df2786fe6a81b696fe2273c2d5f36151bb6af9daf2ce10f057662f7df3ce8ca75970f883a832dbc0c4741e7262be87d79a6eac143298dc9c398ba198f6ba43
7
+ data.tar.gz: d7d155e11b4d1718e072ad5d2eabcb3aad8c2875753eea571bde7e710deee1c88a8acb3244cb01b4055b4c7e648384f91410c42ad576d600ab4c49ffcb39b895
@@ -10,6 +10,7 @@ module Moxml
10
10
  # Mutation return contract (Adapter::Base): returns the native
11
11
  # to keep tracking — same object for in-place adapters, fresh
12
12
  # object for value-object adapters (leptris).
13
+ context.bump_namespace_scope_generation
13
14
  @native = adapter.set_attribute_name(@native, new_name)
14
15
  end
15
16
 
@@ -32,6 +33,7 @@ module Moxml
32
33
  end
33
34
 
34
35
  def value=(new_value)
36
+ context.bump_namespace_scope_generation
35
37
  adapter.set_attribute_value(@native, new_value)
36
38
  end
37
39
 
data/lib/moxml/element.rb CHANGED
@@ -3,10 +3,14 @@
3
3
  module Moxml
4
4
  class Element < Node
5
5
  def name
6
- adapter.node_name(@native)
6
+ # The adapter read is an FFI call plus (on several adapters) a
7
+ # defensive string copy; names only change through name= and
8
+ # native adoption, both of which clear this.
9
+ @name ||= adapter.node_name(@native)
7
10
  end
8
11
 
9
12
  def name=(value)
13
+ @name = nil
10
14
  adapter.set_node_name(@native, value)
11
15
  end
12
16
 
@@ -42,6 +46,7 @@ module Moxml
42
46
  # attributes only; prefixed names replace by namespace URI and
43
47
  # require a declared prefix. Cache coherence is the resolver's.
44
48
  def []=(name, value)
49
+ context.bump_namespace_scope_generation
45
50
  Moxml::AttributeResolver.assign(self, name, normalize_xml_value(value))
46
51
  end
47
52
 
@@ -49,13 +54,30 @@ module Moxml
49
54
  # bare names match only no-namespace attributes; prefixed names
50
55
  # resolve through in-scope declarations to expanded names.
51
56
  def [](name)
52
- Moxml::AttributeResolver.resolve(self, name)&.value
57
+ cache = attribute_read_cache
58
+ key = name.to_s
59
+ unless cache.key?(key)
60
+ cache[key] = Moxml::AttributeResolver.resolve(self, key)
61
+ end
62
+ cache[key]&.value
53
63
  end
54
64
 
55
65
  def attribute(name)
56
66
  Moxml::AttributeResolver.resolve(self, name)
57
67
  end
58
68
 
69
+ # Resolution reads the element.s in-scope namespaces, so the
70
+ # cache rides the context.s namespace-scope generation clock —
71
+ # every attribute or namespace mutation anywhere bumps it.
72
+ def attribute_read_cache
73
+ generation = context.namespace_scope_generation
74
+ if @attribute_cache_generation != generation
75
+ @attribute_cache = {}
76
+ @attribute_cache_generation = generation
77
+ end
78
+ @attribute_cache
79
+ end
80
+
59
81
  # Returns attribute value by name (used by XPath engine)
60
82
  def get(attr_name)
61
83
  self[attr_name]
@@ -70,6 +92,7 @@ module Moxml
70
92
  end
71
93
 
72
94
  def remove_attribute(name)
95
+ context.bump_namespace_scope_generation
73
96
  Moxml::AttributeResolver.remove(self, name)
74
97
  self
75
98
  end
@@ -223,9 +246,13 @@ module Moxml
223
246
  children
224
247
  end
225
248
 
226
- # Called by Attribute#remove to invalidate the cached attributes
249
+ # Called by Attribute#remove and the attribute mutators. Clears
250
+ # the attribute list and the resolved-read cache, and bumps the
251
+ # context generation so cross-wrapper reads recompute.
227
252
  def invalidate_attribute_cache!
228
253
  @attributes = nil
254
+ @attribute_cache = nil
255
+ context.bump_namespace_scope_generation
229
256
  end
230
257
 
231
258
  # Clear the namespace caches and bump the context's scope
data/lib/moxml/node.rb CHANGED
@@ -25,10 +25,18 @@ module Moxml
25
25
  context.unregister_wrapper(@native)
26
26
  @native = new_native
27
27
  context.register_wrapper(new_native, self)
28
+ clear_native_memo!
28
29
  end
29
30
  self
30
31
  end
31
32
 
33
+ # Wrapper-local memos derived from the native (name, attribute
34
+ # reads) die with the native they were computed from.
35
+ def clear_native_memo!
36
+ @name = nil
37
+ @attribute_cache = nil
38
+ end
39
+
32
40
  def document
33
41
  Document.wrap(adapter.document(@native), context)
34
42
  end
data/lib/moxml/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Moxml
4
- VERSION = "0.5.23"
4
+ VERSION = "0.5.24"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moxml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.23
4
+ version: 0.5.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-09-01 00:00:00.000000000 Z
11
+ date: 2026-09-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  Moxml is a unified XML manipulation library that provides a common API