module TrackOpenInstances::ClassMethods
Contains class-level methods added to classes including TrackOpenInstances
Public Instance Methods
Source
# File lib/track_open_instances.rb, line 137 def add_open_instance(instance) @open_instances_mutex.synchronize do @open_instances[instance] = OpenInstance.new(instance, caller_locations(3)) end end
Adds an instance to the tracking list (thread-safe)
Typically called automatically by the instance’s ‘initialize` method.
@param instance [Object] The instance to add
@return [void]
@api private
Source
# File lib/track_open_instances.rb, line 249 def assert_no_open_instances report = open_instances_report raise(report.to_s) if report end
Asserts that no instances of the class remain unclosed
Commonly used in test suite teardown blocks to enure that all resources were released.
@example
# In RSpec teardown (e.g., after(:each)) MyResource.assert_no_open_instances
@raise [RuntimeError] If any instances are found unclosed with a report of unclosed instances
@return [void]
@api public
Source
# File lib/track_open_instances.rb, line 169 def open_instance_count @open_instances_mutex.synchronize do @open_instances.size end end
The number of currently open instances
@example
res1 = MyResource.new res2 = MyResource.new MyResource.open_instance_count #=> 2
@return [Integer]
@api public
Source
# File lib/track_open_instances.rb, line 122 def open_instances @open_instances_mutex.synchronize do @open_instances.dup.freeze end end
@!attribute [r] open_instances
Direct access to the internal list of tracked instances
Note: This returns all instances ever tracked unless explicitly removed. Use ‘open_instances` for checking leaks. Direct use is uncommon.
@example
# Assuming MyResource includes TrackOpenInstances res1 = MyResource.new res2 = MyResource.new res1.close MyResource.open_instances.keys #=> [#<MyResource... object_id=res2>] (after res1 removed)
@return [Hash{Object => OpenInstance}] The raw list of currently tracked instances
@api private
Source
# File lib/track_open_instances.rb, line 191 def open_instances_report @open_instances_mutex.synchronize do return nil if @open_instances.count.zero? String.new.tap do |report| report << open_instances_report_header report << open_instances_report_body end end end
Generates a report string listing unclosed instances and their creation stacks
Useful for debugging resource leaks. Returns nil if no instances are unclosed.
@example
res = MyResource.new puts MyResource.open_instances_report There is 1 open MyResource instance(s): - object_id=701 Created at: (caller stack line 1) (caller stack line 2)\n..."
@return [String, nil] A formatted report string or nil if none are open
@api public
Source
# File lib/track_open_instances.rb, line 222 def open_instances_report_body String.new.tap do |body| @open_instances.each do |instance, open_instance| body << " - object_id=#{instance.object_id}\n" body << " Call stack when created:\n" open_instance.creation_stack.each do |location| body << " #{location.path}:#{location.lineno}:in `#{location.label}'\n" end end end end
The body of the report detailing each open instance
@return [String]
@api private
Source
# File lib/track_open_instances.rb, line 208 def open_instances_report_header count = @open_instances.count class_name = name || 'anonymous class' "There #{count == 1 ? 'is' : 'are'} #{count} " \ "open #{class_name} instance#{count == 1 ? '' : 's'}:\n" end
The header string for the report
@return [String]
@api private
Source
# File lib/track_open_instances.rb, line 152 def remove_open_instance(instance) @open_instances_mutex.synchronize do @open_instances.delete(instance) end end
Removes an instance from the tracking list (thread-safe)
Typically called automatically by the instance’s ‘close` method.
@param instance [Object] The instance to remove
@return [void]
@api private