Kernel#puts
puts(*objects) -> nil puts is a Kernel method that writes one or more objects to standard output (stdout), appending a newline character after each object. It’s the most common way to output text in Ruby scripts and is often used for debugging and displaying information to users.
Syntax
puts obj
puts obj1, obj2, obj3
puts *objects
The three forms shown above are equivalent in practice: you can pass a single argument, several arguments separated by commas, or splat an array of values. Ruby calls to_s on each argument before writing it, so you never have to convert objects to strings manually before passing them to puts.
Parameters
| Parameter | Description |
|---|---|
| *objects | One or more objects to output. Each object is converted to a string using to_s and followed by a newline. |
Examples
Basic Usage
puts "Hello, World!"
# Hello, World!
puts "Line 1"
puts "Line 2"
# Line 1
# Line 2
Each call to puts appends a newline, so two separate calls produce two separate lines. This is the most common pattern in Ruby scripts: a short message followed by a newline, with no extra formatting needed. The behaviour is predictable enough that even a reader new to the language can guess what the output will be.
Multiple Objects
puts "Name:", "Alice", "Age:", 30
# Name:
# Alice
# Age:
# 30
puts accepts a variable number of arguments and writes each one on its own line. This variadic signature means you can pass several unrelated values in a single call without concatenating them into a string first, which keeps the call site clean when you are printing a mix of labels and data.
Arrays
arr = ["apple", "banana", "cherry"]
puts arr
# apple
# banana
# cherry
When you pass an array to puts, Ruby flattens it to one element per line automatically. This is convenient when you want to list items in the terminal without writing a loop, and it is one of the behaviours that distinguishes puts from print — the latter would dump the array in its bracket notation instead of expanding the elements.
nil and Booleans
puts nil # (outputs empty line)
puts true # true
puts false # false
Each of these produces output that matches what you would see in irb for the same value: nil becomes an empty line because nil.to_s returns "", while true and false convert to their lowercase string representations. This consistency is why puts feels natural in scripts — there are no surprising type-dependent behaviours to remember.
Common Patterns
Debugging
def calculate_total(prices)
total = prices.sum
puts "Debug: prices = #{prices.inspect}, total = #{total}"
total
end
Debugging with puts is quick and effective for small scripts because you can drop a line anywhere without setting up a logger or configuring output levels. The inspect call on prices makes the array content readable, which is a small habit that pays off when the variable holds more than a simple scalar value.
Formatted Output
name = "Bob"
age = 25
puts "Name: %s, Age: %d" % [name, age]
# Name: Bob, Age: 25
Format strings with % give you alignment control that plain interpolation does not, though modern Ruby often prefers string interpolation with format or sprintf-style helpers for readability. The core idea stays the same: puts writes whatever string you feed it, so any formatting must happen before the call.
Writing to stderr
puts always writes to stdout. For stderr, use $stderr.puts:
$stderr.puts "Error: something went wrong"
Differences from similar methods
| Method | Newline | Return Value | Special Behavior |
|---|---|---|---|
puts | Yes | nil | Adds newline after each object |
print | No | nil | No newline |
p | Yes | The object(s) | Uses inspect instead of to_s |
printf | No | nil | Formatted output (C-style) |
print vs puts
print "Hello"
print "World"
# HelloWorld
puts "Hello"
puts "World"
# Hello
# World
When you need consecutive output without line breaks between items, print gives you that control — it writes exactly what you ask for and nothing more. The trade-off is that you have to manage spacing yourself, which can make the output harder to scan. For most scripts, the automatic newline from puts keeps the output tidy without extra work.
p vs puts
puts "hello\n" # hello (interprets escape)
p "hello\n" # "hello\n" (shows raw string with newline literal)
These two methods serve different purposes: puts is for human-readable output where you want the content to look natural on the terminal, and p is for debugging where seeing the raw Ruby representation matters more than readability. The difference becomes visible as soon as a string contains escape sequences or special characters — puts renders them, p shows the literal source form.
choosing puts for output
puts is the right tool when the program should speak in simple, readable lines. It is the default choice for console output because it keeps text moving with a newline and turns arrays into one line per item, which is often exactly what you want in scripts and quick tools. The behavior is straightforward enough that most readers can predict the output at a glance.
Because it uses to_s, puts is best when the user-facing text matters more than the exact object shape. If you need to inspect the structure of a value instead, p or pp will show more detail. For plain output, though, puts stays easy to understand and easy to reuse.
That separation between readable output and object inspection is why puts stays such a common default. It keeps the code simple when the goal is just to speak a line of text to the terminal.
# Readable output for users
puts "Results: #{items.size} found"
# Object inspection for debugging
p items # shows raw structure with quotes and brackets
keeping plain output truly plain
puts works well when the message is meant for a person reading the terminal and does not need careful formatting. It strikes a balance between simplicity and readability — the automatic newline keeps messages from running together, and the to_s conversion means you can pass almost any Ruby object without worrying about its type. That makes it a natural fit for progress notes, confirmations, and simple debugging lines:
puts "✓ Loaded #{items.count} records"
puts "Connecting to #{host}..."
puts "Done."
The newline behaviour also keeps stacked messages readable without extra effort. If the output needs alignment or a more formal shape, another method is usually a better fit, but for clear everyday messages, puts stays hard to beat.