Kernel#block_given?
block_given? -> true or false block_given? (also available as iterator?) is a Kernel method that checks whether the current method was called with a block. It returns true if a block is associated with the current call, and false otherwise. This method is essential for writing flexible methods that can behave differently depending on whether a caller provides a block.
Syntax
block_given?
Parameters
This method takes no parameters.
Because block_given? is defined on Kernel, it is available inside every method in every object without any explicit include or require. That means you can use it in plain scripts, Rails models, or custom DSLs without any setup at all.
Examples
Basic usage
def greet
if block_given?
yield
else
puts "Hello!"
end
end
greet { puts "Hello from the block!" }
# Hello from the block!
greet
# Hello!
The if block_given? guard lets a single method serve two different callers: one that wants custom behavior through a block and another that wants a sensible default without any extra ceremony. This pattern avoids duplicating the method for each case.
Checking for a block before yielding
def process_items(items)
if block_given?
items.map { |item| yield item }
else
items
end
end
result = process_items([1, 2, 3]) { |n| n * 2 }
# => [2, 4, 6]
result = process_items([1, 2, 3])
# => [1, 2, 3]
When the block is absent, returning the original collection with no changes is a common default for iterator-style methods. This gives callers a predictable identity operation that they can compose without extra guards. The block is a transform pass that the caller chooses to engage or skip, and the method signature stays the same in both cases.
Common Patterns
Optional block with custom behavior
def configure
config = { timeout: 30, retries: 3 }
if block_given?
yield(config)
end
config
end
config = configure do |c|
c[:timeout] = 60
c[:retries] = 5
end
# => { timeout: 60, retries: 3 }
config = configure
# => { timeout: 30, retries: 3 }
The configuration example shows yield(config) passing a mutable object into the block. The caller can read or modify it, and the method returns the object afterward regardless of what the block did. This is a common pattern for DSLs and setup helpers that want to stay compact.
Building strings conditionally
def build_message(base)
message = base
if block_given?
message = yield(message)
end
message
end
build_message("Hello") { |m| m + ", World!" }
# => "Hello, World!"
build_message("Hello")
# => "Hello"
When the method returns a string that may or may not be transformed by a block, the caller gets a consistent return type either way. The block is purely additive — it can wrap, append, or transform the base message, but the method’s contract stays the same.
Errors
Calling yield without a block raises a LocalJumpError. Always check block_given? before using yield to prevent this error.
def unsafe
yield # Raises LocalJumpError if no block given
end
def safe
yield if block_given? # Safe
end
The yield if block_given? idiom is the simplest and most common guard in Ruby. It avoids the LocalJumpError entirely and reads as a single intention: “run the block if one was given, otherwise do nothing.” When the block is missing, execution continues past the yield without any noise.
Checking for an optional block
block_given? is most helpful when a method can do useful work in either mode: with a block or without one. The check lets the code choose a default behavior, return an enumerator, or yield custom work only when the caller asks for it. That keeps the public API flexible while still making the control flow easy to read. A short if block_given? branch is often the clearest way to show that choice.
It also keeps the method honest about what happens if no block arrives. Instead of failing later in a less obvious place, the method can decide up front whether it is ready to yield. That makes the code easier to maintain and easier to explain in documentation or examples.
The check is small, but it often shapes the whole API because it tells the caller whether the method can act like a mini iterator or whether it should just return a default value. That flexibility is one of the reasons block-aware methods feel so natural in Ruby. The code stays simple, and the caller gets one method that adapts to both use cases.
When used well, the check keeps the method from needing separate names for the block and non-block cases. That can make a small API feel more polished without adding much code. The important part is that the fallback path is still clear enough to understand on its own, so the block remains an option instead of a mystery.