module ObjectSpace include System::Runtime::InteropServices NIL_OBJECT_ID = 4.0 def self.wrapped_ids @wrapped_ids ||= {} end def self.id2ref(object_id,ignore_error=false) object_id = object_id.to_f if (!object_id.is_a?(Float)) if self.wrapped_ids.has_key?(object_id) then object_handle = self.wrapped_ids[object_id] if object_handle.is_allocated && (object_id == NIL_OBJECT_ID || object_handle.target === false || object_handle.target) then object_handle.target else self.wrapped_ids.delete(object_id) raise Exception.new("Object with id '#{object_id}' doesn't exist anymore.") if !ignore_error end else raise Exception.new("Object with id '#{object_id}' doesn't exist or not wrapped.") if !ignore_error end end def self.ref2id(object,object_id) object_id = object_id.to_f if (!object_id.is_a?(Float)) if self.wrapped_ids.has_key?(object_id) then old_object = id2ref(object_id, true) raise Exception.new("There are two objects with id '#{object_id}': '#{object}' ? '#{old_object}'") unless old_object.equal?(object) end unless self.wrapped_ids.has_key?(object_id) then object_handle = GCHandle.alloc(object, GCHandleType.Weak) if object_handle.is_allocated then self.wrapped_ids[object_id] = object_handle else raise Exception.new("Object with id '#{object_id}' couldn't be wrapped.") end end object_id end # MEMO: adding non-changing object id's ref2id(nil, nil.object_id) ref2id(true, true.object_id) ref2id(false, false.object_id) end