p vs puts in Ruby

Viewed 71492

Is there any difference between p and puts in Ruby?

8 Answers

p foo prints foo.inspect followed by a newline, i.e. it prints the value of inspect instead of to_s, which is more suitable for debugging (because you can e.g. tell the difference between 1, "1" and "2\b1", which you can't when printing without inspect).

It is also important to note that puts "reacts" to a class that has to_s defined, p does not. For example:

class T
   def initialize(i)
      @i = i
   end
   def to_s
      @i.to_s
   end
end

t = T.new 42
puts t   => 42
p t      => #<T:0xb7ecc8b0 @i=42>

This follows directly from the .inspect call, but is not obvious in practice.

p foo is the same as puts foo.inspect

These 2 are equal:

p "Hello World"  
puts "Hello World".inspect

(inspect gives a more literal view of the object compared to to_s method)

This may illustrate one of the key differences which is that p returns the value of what is passed to it, where as puts returns nil.

def foo_puts
  arr = ['foo', 'bar']
  puts arr
end

def foo_p
  arr = ['foo', 'bar']
  p arr
end

a = foo_puts
=>nil
a
=>nil

b = foo_p
=>['foo', 'bar']
b
['foo', 'bar']

Benchmark shows puts is slower

require 'benchmark'
str = [*'a'..'z']
str = str*100
res = Benchmark.bm do |x|
  x.report(:a) { 10.times {p str} }
  x.report(:b) { 10.times {puts str} }
end
puts "#{"\n"*10}"
puts res

0.010000   0.000000   0.010000 (  0.047310)
0.140000   0.090000   0.230000 (  0.318393)

p method will print more extensive debuggable message, where puts will prettify message code.

e.g see below lines of code:

msg = "hey, Use \#{ to interpolate expressions"
puts msg #clean msg
p msg #shows \ with #

output will be

hey, Use #{ to interpolate expressions
"hey, Use \#{ to interpolate expressions"

see output pic for more clarity

Related