From 83702f7157a8c74dd4d7d6d79dea78d90a7b6570 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Fri, 12 Jul 2024 12:23:24 +0200 Subject: [PATCH] [ruby/pp] 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. https://github.com/ruby/pp/commit/4e9f6c2de0 --- 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 2adceea3e2..4bb1002f7b 100644 --- a/lib/pp.rb +++ b/lib/pp.rb @@ -189,7 +189,7 @@ class PP < PrettyPrint 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 @@ class PP < PrettyPrint 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 e515e920dc..16f6fa7485 100644 --- a/test/test_pp.rb +++ b/test/test_pp.rb @@ -125,6 +125,11 @@ class PPInspectTest < Test::Unit::TestCase 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