From a045f6582b6e3cbcad394e89d2a0d52e61e7c482 Mon Sep 17 00:00:00 2001 From: Alexander Momchilov Date: Mon, 18 Dec 2023 12:56:37 -0500 Subject: [PATCH] Remove `object_id` use in `Set#inspect` --- lib/set.rb | 50 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/lib/set.rb b/lib/set.rb index a946d3c..99a5d3e 100644 --- a/lib/set.rb +++ b/lib/set.rb @@ -812,23 +812,51 @@ def join(separator=nil) to_a.join(separator) end + def self.__inspect_supports_identity_set? + true + end + InspectKey = :__inspect_key__ # :nodoc: - # Returns a string containing a human-readable representation of the - # set ("#"). - def inspect - ids = (Thread.current[InspectKey] ||= []) + # We share the same `ids` value as `OpenStruct#inspect`, so we need to use an identity Set + # only we're using a newer version of the `ostruct` gem which is also using an identity Set. + if defined?(OpenStruct.__inspect_supports_identity_set?) && OpenStruct.__inspect_supports_identity_set? - if ids.include?(object_id) - return sprintf('#<%s: {...}>', self.class.name) + # Returns a string containing a human-readable representation of the + # set ("#"). + def inspect + ids = (Thread.current[InspectKey] ||= Set.new.compare_by_identity) + + unless ids.add?(self) + return sprintf('#<%s: {...}>', self.class.name) + end + + begin + return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2]) + ensure + ids.remove(self) + end end - ids << object_id - begin - return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2]) - ensure - ids.pop + else + + # Returns a string containing a human-readable representation of the + # set ("#"). + def inspect + ids = (Thread.current[InspectKey] ||= []) + + if ids.include?(object_id) + return sprintf('#<%s: {...}>', self.class.name) + end + + ids << object_id + begin + return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2]) + ensure + ids.pop + end end + end alias to_s inspect