Skip to content

Commit

Permalink
Support BasicObject
Browse files Browse the repository at this point in the history
  • Loading branch information
st0012 committed Apr 25, 2023
1 parent a7e0499 commit 03ce70e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 5 deletions.
25 changes: 20 additions & 5 deletions lib/pp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ class << self
end
end

M_RESPOND_TO = Object.instance_method(:respond_to?)
private_constant :M_RESPOND_TO

module PPMethods

# Yields to a block
Expand Down Expand Up @@ -188,7 +191,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}
Expand All @@ -197,7 +200,12 @@ def pp(obj)

begin
push_inspect_key(obj)
group {obj.pretty_print self}

if M_RESPOND_TO.bind_call(obj, :pretty_print)
group { obj.pretty_print self }
else
group { Object.instance_method(:pretty_print).bind_call(obj, self) }
end
ensure
pop_inspect_key(obj) unless PP.sharing_detection
end
Expand Down Expand Up @@ -266,8 +274,15 @@ def seplist(list, sep=nil, iter_method=:each) # :yield: element

# A present standard failsafe for pretty printing any given Object
def pp_object(obj)
instance_variables =
if M_RESPOND_TO.bind_call(obj, :pretty_print_instance_variables)
obj.pretty_print_instance_variables
else
Object.instance_method(:pretty_print_instance_variables).bind_call(obj)
end

object_address_group(obj) {
seplist(obj.pretty_print_instance_variables, lambda { text ',' }) {|v|
seplist(instance_variables, lambda { text ',' }) {|v|
breakable
v = v.to_s if Symbol === v
text v
Expand Down Expand Up @@ -325,7 +340,7 @@ def pretty_print(q)
end
if inspect_method && inspect_method.owner != Kernel
q.text self.inspect
elsif !inspect_method && self.respond_to?(:inspect)
elsif !inspect_method && M_RESPOND_TO.bind_call(self, :inspect)
q.text self.inspect
else
q.pp_object(self)
Expand All @@ -346,7 +361,7 @@ def pretty_print_cycle(q)
# This method should return an array of names of instance variables as symbols or strings as:
# +[:@a, :@b]+.
def pretty_print_instance_variables
instance_variables.sort
Object.instance_method(:instance_variables).bind_call(self).sort
end

# Is #inspect implementation using #pretty_print.
Expand Down
11 changes: 11 additions & 0 deletions test/test_pp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ def test_list0123_11
assert_equal("[0,\n 1,\n 2,\n 3]\n", PP.pp([0,1,2,3], ''.dup, 11))
end

def test_basic_object
foo_class = Class.new(Object) do
def initialize
@obj = BasicObject.new
end
end
assert_match(/#<BasicObject:.*>/, PP.pp(BasicObject.new, ''.dup, 12))
assert_match(/\[0,\n 1,\n 2,\n #<BasicObject:.*>\]\n/, PP.pp([0,1,2, BasicObject.new], ''.dup, 12))
assert_match(/#<#<Class:.*>:.*\n @obj=\n #<BasicObject:.*>>/, PP.pp(foo_class.new, ''.dup, 12))
end

OverriddenStruct = Struct.new("OverriddenStruct", :members, :class)
def test_struct_override_members # [ruby-core:7865]
a = OverriddenStruct.new(1,2)
Expand Down

0 comments on commit 03ce70e

Please sign in to comment.