67

Why do this Ruby object both a to_s and inspect methods that appear to do the same thing?

The p method calls inspect and puts/print calls to_s for representing the object.

If I run

class Graph
  def initialize
    @nodeArray = Array.new
    @wireArray = Array.new
  end
  def to_s # called with print / puts
    "Graph : #{@nodeArray.size}"
  end
  def inspect # called with p
    "G"
  end
end

if __FILE__ == $0
  gr = Graph.new
  p gr
  print gr
  puts gr
end

I get

G
Graph : 0
Graph : 0
  • Then, why does Ruby have two functions do the same thing? What is the difference between to_s and inspect?
  • And what's the difference between puts, print, and p?

If I comment out the to_s or inspect function, I get as follows.

#<Graph:0x100124b88>
#<Graph:0x100124b88>
Guy C
  • 6,970
  • 5
  • 30
  • 30
prosseek
  • 182,215
  • 215
  • 566
  • 871

9 Answers9

53

inspect is used more for debugging and to_s for end-user or display purposes.

For example, [1,2,3].to_s and [1,2,3].inspect produce different output.

David
  • 7,011
  • 1
  • 42
  • 38
  • 49
    I am probably doing something wrong, but to me in IRB the outputs were the same: `"[1, 2, 3]"`. On the other hand, `nil.to_s` and `nil.inspect` produced `""` and `"nil"` respectively. – BreakPhreak Jun 02 '11 at 11:39
  • 2
    same here, to_s and inspect return same output (as of March 2013) – aug2uag Mar 10 '13 at 05:35
  • 1
    `[1,2,3].to_s => "123"`; `[1,2,3].inspect => "[1, 2, 3]"`. `"#{...}"` uses the former; `p ...` uses the latter. – cdunn2001 May 12 '13 at 21:07
  • 27
    Using ruby 1.8.7 I get `[1,2,3].to_s => "123"`. With ruby 2.0.0 I get `[1,2,3].to_s => "[1, 2, 3]"`. So the given example is either true or not true depending on what version you are talking about. – Burhan Ali May 12 '13 at 21:37
  • According to release docs, starting in 2.0.0 "Object#inspect does always return a string like # instead of delegating to #to_s. [#2152]", so the difference between to_s and inspect is probably clearer in IRB once you upgrade. See: http://www.ruby-lang.org/en/news/2013/02/24/ruby-2-0-0-p0-is-released/ – Stephen Dec 22 '13 at 06:57
  • Weird, for Regexp on 2.1.1 it feels like the contrary: `/a/.inspect` gives `/a/` which is human readable, but `/a/.to_s` gives `(?-mix:a)`. – Ciro Santilli OurBigBook.com Jun 26 '14 at 08:01
  • Ruby 1.9 changed `Array#to_s` to be `Array#inspect`. https://stackoverflow.com/q/3960392/ – Yasushi Shoji Mar 08 '18 at 14:22
  • 2
    As of today, version 2.6.3, I get the same output for both. – Pablo Jul 14 '19 at 22:04
33

inspect is a method that, by default, tells you the class name, the instance's object_id, and lists off the instance's instance variables.

print and puts are used, as you already know, to put the value of the object's to_s method to STDOUT. As indicated by Ruby's documentation, Object#to_s returns a string representing the object -- used for end-user readability.

print and puts are identical to each other except for puts automatically appends a newline, while print does not.

Mark Rushakoff
  • 249,864
  • 45
  • 407
  • 398
  • 1
    `Time.new.inspect` isn't showing the `class` name and `object_id`, it rather prints `"2016-11-10 13:05:45 +0530"` (Time in `string`) – Radix Nov 10 '16 at 07:36
14

To compare with Python, to_s is like __str__ and inspect is like __repr__. to_s gives you a string, whereas inspect gives you the string representation of the object. You can use the latter to construct an object if you wish.

grokus
  • 18,046
  • 9
  • 29
  • 35
  • But in Python `eval(repr(z)) == z` should be True: how do you achieve this in Ruby? – wchargin Dec 26 '13 at 19:56
  • 1
    `eval(repr(z)) == z` is a myth. It's very rarely a useful thing to do, and has lots of potential problems. This article is a good start: http://stupidpythonideas.blogspot.com.au/2013/11/repr-eval-bad-idea.html – Cam Jackson Apr 29 '14 at 02:19
  • Alex Martelli expresses the same sentiment here: http://stackoverflow.com/a/1436756/665488. It's just too hard to keep your `__repr__`s working like that, for very little real practical advantage. – Cam Jackson Apr 29 '14 at 02:25
6

For anyone arriving here after starting out with Ruby Koans, a simple example of where to_s and inspect differ in output is this:

nil.to_s     # will yield an empty string, ie ""
nil.inspect  # will yield the string "nil"
seymore_strongboy
  • 934
  • 10
  • 16
5

Further, there is a to_str method on certain objects, which you would call when you need a String-like object, and not just a string representation. (Try in IRB: [1,2,3].to_str and it will fail, yet [1,2,3].to_s will not.) I feel I should mention this because I've been bitten by it before :)

RobH
  • 568
  • 5
  • 13
  • 1
    Not sure what you mean with a string-like object, but as far as I understood, `to_s` is meant for string representation and as such is used on interpolation, whereas `to_str` is meant for implicit conversions such as type coersion. – Pelle Jun 07 '17 at 19:05
3

puts generally prints the result of applying to_s on an object, while p prints the result of inspecting the object.

There is a subtle difference between inspect and to_s:

  • inspect, when applied on an object, returns the object hex code along with the instance variable
  • to_s, when applied on an object,returns only the object hex code

    class Item
     def initialize(abc)
      @abc=abc
     end
    end
    
    x= Item.new(22)
    
    puts x         #prints object x hex code  
    puts x.inspect #prints object x hex code WITH INSTANCE VARIABLE @abc 
    puts x.to_s    #prints object x hex code
    
    p x            #prints object x hex code WITH INSTANCE VARIABLE @abc
    p x.inspect    #prints object x hex code WITH INSTANCE VARIABLE @abc
    p x.to_s       #prints object x hex code
pintua
  • 63
  • 5
2

Answer from Chris Pine's Learn To Program book

"The inspect method is a lot like to_s, except that the string it returns tries to show you the ruby code for building the object you passed it."

Thus the inspect method will return an array for example like this...

[25, 16, 9, 4, 1, 0] 

Where as puts / to_s will return

25
16
9
4
1
0
Ari
  • 45
  • 5
1
2.0.0p195 :075 > puts (1..5).to_a                  # Put an array as a string.
1
2
3
4
5
=> nil 
2.0.0p195 :076 > puts (1..5).to_a.inspect          # Put a literal array.
[1, 2, 3, 4, 5]
=> nil 
2.0.0p195 :077 > puts :name, :name.inspect
name
:name
=> nil 
2.0.0p195 :078 > puts "It worked!", "It worked!".inspect    
It worked! 
"It worked!"
=> nil 
2.0.0p195 :079 > p :name                           # Same as 'puts :name.inspect'
:name
=> :name 

From the Rails Tutorial

Feuda
  • 2,335
  • 30
  • 28
0

Refer following link for more information and examples explaining difference between "to_s" and "inspect" as well as difference between "puts" and "p". https://rubymonk.com/learning/books/4-ruby-primer-ascent/chapters/45-more-classes/lessons/108-displaying-objects

Gitanjali
  • 125
  • 1
  • 2
  • 6