Getting a Human-Readable Printout of Any Object

Problem

You want to look at a natural-looking rendition of a given object.

Solution

Use Object#inspect. Nearly all the time, this method will give you something more readable than simply printing out the object or converting it into a string.

	a = [1,2,3]
	puts a
	# 1
	# 2
	# 3

	puts a.to_s
	# 123

	puts a.inspect
	# [1, 2, 3]
	puts /foo/
	# (?-mix:foo)
	puts /foo/.inspect
	# /foo/
	f = File.open('foo', 'a')
	puts f
	# #
	puts f.inspect
	# #

 

Discussion

Even very complex data structures can be inspected and come out looking just like they would in Ruby code to define that data structure. In some cases, you can even run the output of inspect through eval to recreate the object.

	periodic_table = [{ :symbol => "H", :name => "hydrogen", :weight => 1.007 },
	 { :symbol => "Rg", :name => "roentgenium", :weight => 272 }]
	puts periodic_table.inspect
	# [{:symbol=>"H", :name=>"hydrogen", :weight=>1.007},
	# {:symbol=>"Rg", :name=>"roentgenium", :weight=>272}]

	eval(periodic_table.inspect)[0]
	# => {:symbol=>"H", :name=>"hydrogen", :weight=>1.007}

By default, an object's inspect method works the same way as its to_s method.[3] Unless your classes override inspect, inspecting one of your objects will yield a boring and not terribly helpful string, containing only the object's class name, object_id, and instance variables:

[3] Contrary to what ri Object#inspect says, Object#inspect does not delegate to the Object#to_s method: it just happens to work a lot like Object#to_s. If you only override to_s, inspect won't be affected.

	class Dog
	 def initialize(name, age)
	 @name = name
	 @age = age * 7 #Compensate for dog years
	 end
	end

	spot = Dog.new("Spot", 2.1)
	spot.inspect
	# => "#"

That's why you'll help out your future self by defining useful inspect methods that give relevant information about the objects you'll be instantiating.

	class Dog
	 def inspect
	 ""
	 end
	 def to_s
	 inspect
	 end
	end
	spot.inspect
	# => ""

Or, if you believe in being able to eval the output of inspect:

	class Dog
	 def inspect
	 %{Dog.new("#{@name}", #{@age/7})}
	 end
	end
	spot.inspect
	# => "Dog.new("Spot", 2.1)"
	eval(spot.inspect).inspect
	# => "Dog.new("Spot", 2.1)"

Just don't automatically eval the output of inspect, because, as always, that's dangerous:

	strange_dog_name = %{Spot", 0); puts "Executing arbitrary Ruby…"; puts("}
	spot = Dog.new(strange_dog_name, 0)
	puts spot.inspect
	# Dog.new("Spot", 0); puts "Executing arbitrary Ruby…"; puts("", 0)
	eval(spot.inspect)
	# Executing arbitrary Ruby…
	#
	# 0


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net