1
0
Fork 0
mirror of https://github.com/awesome-print/awesome_print synced 2023-03-27 23:22:34 -04:00

Merge pull request #183 from clonezone/paranoid-to_hash

Be careful about invoking #to_hash on arbitrary objects.
This commit is contained in:
Mauro George 2015-02-05 19:36:05 -02:00
commit b8f114c403
2 changed files with 70 additions and 3 deletions

View file

@ -62,9 +62,9 @@ module AwesomePrint
#------------------------------------------------------------------------------
def awesome_self(object, type)
if @options[:raw] && object.instance_variables.any?
awesome_object(object)
elsif object.respond_to?(:to_hash)
awesome_hash(object.to_hash)
return awesome_object(object)
elsif hash = convert_to_hash(object)
awesome_hash(hash)
else
colorize(object.inspect.to_s, type)
end
@ -318,6 +318,22 @@ module AwesomePrint
# Utility methods.
#------------------------------------------------------------------------------
def convert_to_hash(object)
if ! object.respond_to?(:to_hash)
return nil
end
if object.method(:to_hash).arity != 0
return nil
end
hash = object.to_hash
if ! hash.respond_to?(:keys) || ! hash.respond_to?('[]')
return nil
end
return hash
end
def align(value, width)
if @options[:multiline]
if @options[:indent] > 0

View file

@ -708,5 +708,56 @@ EOS
my = My.new
expect { my.methods.ai(:plain => true) }.not_to raise_error
end
describe "should handle a class that defines its own #to_hash method" do
it "that takes arguments" do
class My
def to_hash(a, b)
end
end
my = My.new
expect { my.ai(:plain => true) }.not_to raise_error
end
it "that returns nil" do
class My
def to_hash()
return nil
end
end
my = My.new
expect { my.ai(:plain => true) }.not_to raise_error
end
it "that returns an object that doesn't support #keys" do
class My
def to_hash()
object = Object.new
object.define_singleton_method('[]') { return nil }
return object
end
end
my = My.new
expect { my.ai(:plain => true) }.not_to raise_error
end
it "that returns an object that doesn't support subscripting" do
class My
def to_hash()
object = Object.new
object.define_singleton_method(:keys) { return [:foo] }
return object
end
end
my = My.new
expect { my.ai(:plain => true) }.not_to raise_error
end
end
end
end