Skip to content

Commit fd27f43

Browse files
committed
Fix recursive Data#inspect
1 parent a65bde3 commit fd27f43

File tree

5 files changed

+21
-9
lines changed

5 files changed

+21
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Compatibility:
2323
* Fix `Kernel#raise` and don't override `cause` at exception re-raising (#3831, @andrykonchin).
2424
* Return a pointer with `#type_size` of 1 for `Pointer#read_pointer` (@eregon).
2525
* Fix `rb_str_locktmp()` and `rb_str_unlocktmp()` to raise `FrozenError` when string argument is frozen (#3752, @andrykonchin).
26+
* Fix `Data#inspect` when data contains a recursive attribute (#3847, @andrykonchin).
2627

2728
Performance:
2829

spec/ruby/core/data/shared/inspect.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,13 @@ def self.name
5050

5151
a.send(@method).should == "#<data DataSpecs::Measure amount=42, unit=#<data DataSpecs::Measure:...>>"
5252
end
53+
54+
it "returns string representation with recursive attribute replaced with ... when an anonymous class" do
55+
klass = Class.new(DataSpecs::Measure)
56+
a = klass.allocate
57+
a.send(:initialize, amount: 42, unit: a)
58+
59+
a.send(@method).should =~ /#<data amount=42, unit=#<data #<Class:0x.+?>:\.\.\.>>/
60+
end
5361
end
5462
end

spec/tags/core/data/inspect_tags.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

spec/tags/core/data/to_s_tags.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/main/ruby/truffleruby/core/data.rb

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,20 @@ def with(**changes)
140140
141141
def inspect
142142
klass = Primitive.class(self)
143-
class_name = Primitive.module_anonymous?(klass) ? '' : "#{Primitive.module_name(klass)} "
144-
members_and_values = to_h.map do |member, value|
145-
if Truffle::CExt.rb_is_local_id(member) or Truffle::CExt.rb_is_const_id(member)
146-
"#{member}=#{value.inspect}"
147-
else
148-
"#{member.inspect}=#{value.inspect}"
143+
144+
return "#<data #{klass}:...>" if Truffle::ThreadOperations.detect_recursion(self) do
145+
class_name = Primitive.module_anonymous?(klass) ? nil : Primitive.module_name(klass)
146+
147+
members_and_values = to_h.map do |member, value|
148+
if Truffle::CExt.rb_is_local_id(member) or Truffle::CExt.rb_is_const_id(member)
149+
"#{member}=#{value.inspect}"
150+
else
151+
"#{member.inspect}=#{value.inspect}"
152+
end
149153
end
154+
155+
return "#<data #{class_name}#{' ' if class_name}#{members_and_values.join(', ')}>"
150156
end
151-
"#<data #{class_name}#{members_and_values.join(', ')}>"
152157
end
153158
alias_method :to_s, :inspect
154159

0 commit comments

Comments
 (0)