[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#<BasicObject:0x[\da-f]+>\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
This commit is contained in:
Jean Boussier 2024-07-12 12:23:24 +02:00 committed by git
parent 107a4da122
commit 83702f7157
2 changed files with 11 additions and 2 deletions

View File

@ -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

View File

@ -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#<BasicObject:0x[\da-f]+>\n\z/, PP.pp(a, ''.dup))
end
end
class PPCycleTest < Test::Unit::TestCase