Question
Is there a difference between p and puts in Ruby? When should each method be used, and how do they display strings, arrays, and other objects?
Short Answer
By the end of this page, you will know that puts is mainly for readable user-facing output, while p is mainly for inspecting values during debugging. You will also understand their different formatting rules and return values.
Concept
p and puts both write output to the console in Ruby, but they have different purposes.
- Use
putswhen you want output that is easy for a person to read. - Use
pwhen you want to see a Ruby-oriented representation of an object, especially while debugging.
The important difference is the conversion method each uses:
putsgenerally displays an object usingto_s.pdisplays an object usinginspect.
For strings, inspect includes quotes and makes invisible characters visible. This helps you identify values such as an empty string, a string containing a newline, or a string with extra spaces.
message = "Hello\nRuby"
puts message
p message
Output:
Hello
Ruby
"Hello\nRuby"
puts prints the string as it would normally appear. p shows Ruby's inspectable form, including the \n escape sequence.
This distinction matters because output is often used for two different audiences:
- Application users, who need clear messages.
- Developers, who need accurate details about values and data types while diagnosing problems.
Mental Model
Think of puts as reading a message aloud to a user. It tries to make the message pleasant and natural to read.
Think of p as putting an object under a magnifying glass for a programmer. It shows details that may not be visible normally, such as quotation marks, escape characters, array brackets, and nil.
For example, these values can look similar with puts:
puts ""
puts " "
puts nil
They each produce a blank-looking line. With p, their differences are visible:
p "" # ""
p " " # " "
p nil # nil
Syntax and Examples
The basic syntax is:
puts object
p object
You can also pass multiple arguments:
puts "Name", "Ada"
p "Name", "Ada"
Strings
name = "Ada"
puts name
p name
Output:
Ada
"Ada"
puts prints the string without quotes. p uses inspect, so the quotes appear.
Arrays
languages = ["Ruby", "Python", "JavaScript"]
puts languages
p languages
Output:
Ruby
Python
JavaScript
["Ruby", "Python", "JavaScript"]
When given an array, puts prints each array element on its own line. p prints the entire array as one Ruby-style value.
Return values
result_from_puts = puts "Done"
result_from_p = p "Done"
p result_from_puts
p result_from_p
Output:
Done
"Done"
nil
"Done"
putsreturnsnil.preturns the object or objects it printed. With one argument, it returns that argument.
Step by Step Execution
Consider this code:
items = ["book", "pen"]
status = nil
puts items
p items
p status
Here is what Ruby does:
-
itemsis assigned an array containing two strings. -
statusis assignednil, meaning it has no value. -
puts itemsreceives an array. Ruby outputs each element separately:book pen -
p itemscallsinspecton the array and outputs one representation of the complete array:["book", "pen"] -
p statusmakes the absence of a value explicit:nil
The full output is:
book
pen
["book", "pen"]
nil
Real World Use Cases
Displaying command-line messages
Use puts for messages intended for a person running a script.
puts "Import completed successfully."
puts "Processed 25 records."
Debugging user input
Use p to verify what was actually received. This is useful when leading spaces or newline characters may be present.
input = gets
p input
If the user types hello and presses Enter, p may show:
"hello\n"
That newline explains why calling input.strip can be necessary.
Inspecting API or JSON data
During development, p can quickly show the shape of a hash or array.
response = { "id" => 7, "active" => true }
p response
Showing reports
Use puts to format readable report lines.
orders.each do |order|
puts "Order ##{order[:id]}: #{order[:total]}"
end
Real Codebase Usage
In real Ruby projects, p is most often a quick debugging tool rather than permanent application output.
Inspect values before a guard clause
def process_email(email)
p email
return if email.nil? || email.empty?
puts "Sending email to #{email}"
end
The p email line helps a developer tell the difference between nil, "", and a string with hidden whitespace.
Debug a transformation pipeline
prices = ["10", "20", "invalid"]
numbers = prices.filter_map do |price|
Integer(price, exception: false)
end
p numbers
This prints the transformed result so a developer can check that invalid data was excluded.
Prefer structured logging for long-term diagnostics
Production applications commonly use a logger instead of leaving p statements in the code.
require "logger"
logger = Logger.new($stdout)
logger.info("Import started")
logger.debug({ imported_count: 25 }.inspect)
A logger can add timestamps, severity levels, and configurable destinations. puts and p remain useful for small scripts, tutorials, tests, and short-lived local debugging.
Use inspect in custom messages when needed
Sometimes you want a readable sentence but also need an exact representation of a value:
username = " "
puts "Received username: #{username.inspect}"
This produces:
Received username: " "
Common Mistakes
Expecting p to produce user-friendly output
# Not ideal for a normal user message
p "Welcome, Ada!"
Output:
"Welcome, Ada!"
Use puts when the quotes are not useful:
puts "Welcome, Ada!"
Using puts when debugging invisible characters
value = " ruby \n"
puts value
The extra spaces and newline are difficult to see. Use p instead:
p value
# " ruby \n"
Assuming puts array prints an array literal
colors = ["red", "blue"]
puts colors
This does not print ["red", "blue"]. It prints each member on a separate line. Use p colors when you need to inspect the array as one object.
Chaining after puts
Because puts returns nil, this fails:
# Broken: puts returns nil
puts("hello").upcase
Ruby raises an error because nil does not have an upcase method. Store or transform the value before printing:
message = "hello".upcase
puts message
Treating p as a replacement for logging
Leaving many p calls in application code can create noisy output and may expose sensitive values. Remove temporary debug output or replace it with an appropriate logger before deployment.
Comparisons
| Feature | puts | p | print |
|---|---|---|---|
| Main purpose | Readable output | Debugging and inspection | Output without automatic line breaks |
| Conversion used | Usually to_s | inspect | Usually to_s |
| Adds a newline? | Yes | Yes | No |
| String output | hello | "hello" | hello |
| Array output | Each element on a separate line | One array representation | Usually uses the array's string form |
| Return value | nil | The printed argument/value | nil |
inspect versus to_s
Most Ruby objects can provide both methods:
value = "Ruby\n"
puts value.to_s
p value.inspect
to_sis usually intended to be readable.inspectis usually intended to be unambiguous for developers.
Custom Ruby classes can define their own to_s and inspect methods, so the exact output can differ by class.
Cheat Sheet
puts value # Readable output; adds newline; returns nil
p value # Debug output via inspect; adds newline; returns value
print value # Readable output; no automatic newline; returns nil
| Need | Choose |
|---|---|
| A message for a person | puts |
See quotes, nil, spaces, or \n | p |
| Inspect an array or hash as one value | p |
| Print array items one per line | puts array |
| Continue output on the same line | print |
Key details:
puts "hi"outputshi.p "hi"outputs"hi".puts [1, 2]outputs1and2on separate lines.p [1, 2]outputs[1, 2].putsreturnsnil;preturns its argument when called with one argument.
FAQ
Should I use p or puts for debugging in Ruby?
Use p for quick debugging because it calls inspect, making strings, arrays, hashes, nil, and escape characters easier to identify.
Why does p put quotes around strings in Ruby?
p uses inspect. Ruby's inspected representation of a string includes quotes so that the value is clear.
Why does puts print every array item on a separate line?
puts handles arrays specially by recursively outputting their elements. This is convenient for displaying a simple list.
Does p add a newline in Ruby?
Yes. Like puts, p adds a newline after its output. Use print if you do not want an automatic newline.
What does puts return?
puts returns nil. It is intended for output as a side effect, not for producing a value to use later.
What does p return?
With one argument, p returns the same object it printed. This can be convenient for temporarily inspecting an expression while keeping its value available.
Can I use puts in production Ruby code?
Yes, especially in small command-line programs. For long-running applications, structured logging is often a better choice for diagnostic messages.
Mini Project
Description
Build a small command-line input checker. It asks for a name, displays a friendly greeting with puts, and uses p to show the exact input received. This demonstrates why inspecting input is useful when users press Enter or type unexpected spaces.
Goal
Create a Ruby script that shows both user-friendly output and debugging-oriented output for the same input.
Requirements
Ask the user to enter a name.
Display the raw input with p.
Remove leading and trailing whitespace from the name.
Display a friendly greeting with puts.
Show a message when the cleaned name is empty.
Keep learning
Related questions
Add a Default Value to an Existing Column in a Rails Migration
Learn how to add or change a default value on an existing database column using Rails Active Record migrations safely.
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.