Class: Moxml::NativeAttachment::Native
- Inherits:
-
Object
- Object
- Moxml::NativeAttachment::Native
- Defined in:
- lib/moxml/native_attachment/native.rb
Overview
Stores Moxml-specific state associated with native adapter objects without polluting their internals.
Uses object_id as key with GC finalizer cleanup to prevent memory leaks. Thread-safe via Monitor (reentrant-safe).
Replaces the anti-pattern of using instance_variable_set/get on foreign library objects (Nokogiri, REXML, Oga, Ox, LibXML nodes).
Instance Method Summary collapse
- #delete(native, key) ⇒ Object
-
#get(native, key) ⇒ Object
Reads are lock-free: MRI Hash#[] is atomic under the GVL, and the only mid-write race (set assigns the inner hash before its key) resolves to a miss — the same answer as "not set yet", which every reader treats conservatively.
-
#initialize ⇒ Native
constructor
A new instance of Native.
- #key?(native, key) ⇒ Boolean
- #none_set?(native, keys) ⇒ Boolean
- #set(native, key, value) ⇒ Object
Constructor Details
#initialize ⇒ Native
Returns a new instance of Native.
22 23 24 25 26 |
# File 'lib/moxml/native_attachment/native.rb', line 22 def initialize @data = {} @finalizer_registered = {} @monitor = Monitor.new end |
Instance Method Details
#delete(native, key) ⇒ Object
58 59 60 |
# File 'lib/moxml/native_attachment/native.rb', line 58 def delete(native, key) @monitor.synchronize { @data[native.object_id]&.delete(key) } end |
#get(native, key) ⇒ Object
Reads are lock-free: MRI Hash#[] is atomic under the GVL, and the only mid-write race (set assigns the inner hash before its key) resolves to a miss — the same answer as "not set yet", which every reader treats conservatively. This method sits on per-element hot paths (entity_bearing? on every serialize).
33 34 35 |
# File 'lib/moxml/native_attachment/native.rb', line 33 def get(native, key) @data[native.object_id]&.[](key) end |
#key?(native, key) ⇒ Boolean
53 54 55 56 |
# File 'lib/moxml/native_attachment/native.rb', line 53 def key?(native, key) h = @data[native.object_id] !h.nil? && h.key?(key) end |
#none_set?(native, keys) ⇒ Boolean
46 47 48 49 50 51 |
# File 'lib/moxml/native_attachment/native.rb', line 46 def none_set?(native, keys) h = @data[native.object_id] return true if h.nil? keys.none? { |key| h.key?(key) } end |
#set(native, key, value) ⇒ Object
37 38 39 40 41 42 43 44 |
# File 'lib/moxml/native_attachment/native.rb', line 37 def set(native, key, value) id = native.object_id @monitor.synchronize do @data[id] ||= {} @data[id][key] = value register_finalizer(native, id) unless @finalizer_registered[id] end end |