From 4e9f6c2de0326117a766f2af484aac40782f42f0 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Fri, 12 Jul 2024 12:23:24 +0200 Subject: [PATCH] Handle BasicObject Right now attempting to pretty print a BasicObject or any other object lacking a few core Object methods will result in an error ``` Error: test_basic_object(PPTestModule::PPInspectTest): NoMethodError: undefined method `is_a?' for an instance of BasicObject lib/pp.rb:192:in `pp' lib/pp.rb:97:in `block in pp' lib/pp.rb:158:in `guard_inspect_key' lib/pp.rb:97:in `pp' test/test_pp.rb:131:in `test_basic_object' 128: 129: def test_basic_object 130: a = BasicObject.new => 131: assert_match(/\A#\n\z/, PP.pp(a, ''.dup)) 132: end 133: end 134: ``` With some fairly small changes we can fallback to `Object#inspect` which is better than an error. --- lib/pp.rb | 8 ++++++-- test/test_pp.rb | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/pp.rb b/lib/pp.rb index 1ec5a88..d3f0f78 100644 --- a/lib/pp.rb +++ b/lib/pp.rb @@ -189,7 +189,7 @@ def pop_inspect_key(id) def pp(obj) # If obj is a Delegator then use the object being delegated to for cycle # detection - obj = obj.__getobj__ if defined?(::Delegator) and obj.is_a?(::Delegator) + obj = obj.__getobj__ if defined?(::Delegator) and ::Delegator === obj if check_inspect_key(obj) group {obj.pretty_print_cycle self} @@ -198,7 +198,11 @@ def pp(obj) begin push_inspect_key(obj) - group {obj.pretty_print self} + group do + obj.pretty_print self + rescue NoMethodError + text Kernel.instance_method(:inspect).bind_call(obj) + end ensure pop_inspect_key(obj) unless PP.sharing_detection end diff --git a/test/test_pp.rb b/test/test_pp.rb index 2fdd5df..45c7691 100644 --- a/test/test_pp.rb +++ b/test/test_pp.rb @@ -125,6 +125,11 @@ def a.to_s() "aaa" end result = PP.pp(a, ''.dup) assert_equal("#{a.inspect}\n", result) end + + def test_basic_object + a = BasicObject.new + assert_match(/\A#\n\z/, PP.pp(a, ''.dup)) + end end class PPCycleTest < Test::Unit::TestCase