Block given? check in Ruby - Time & Space Complexity
We want to understand how checking if a block is given affects the time a Ruby method takes to run.
Specifically, we ask: how does this check grow as input changes?
Analyze the time complexity of the following code snippet.
def greet(name)
if block_given?
yield(name)
else
"Hello, #{name}!"
end
end
result = greet("Alice") { |n| "Hi, #{n.upcase}!" }
This method checks if a block is given and either yields to it or returns a greeting string.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The method performs a single check
block_given?once per call. - How many times: Exactly once each time the method runs.
Checking if a block is given does not depend on the size of the input.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 1 check |
| 100 | 1 check |
| 1000 | 1 check |
Pattern observation: The number of operations stays the same no matter how big the input is.
Time Complexity: O(1)
This means the time to check if a block is given stays constant regardless of input size.
[X] Wrong: "Checking if a block is given takes longer when the input is bigger."
[OK] Correct: The check only looks for a block presence once and does not depend on input size.
Understanding simple checks like block_given? helps you explain how small parts of code behave in terms of speed.
"What if the method called the block multiple times inside a loop? How would the time complexity change?"
Practice
block_given? check inside a method?Solution
Step 1: Understand the purpose of
This method returns true if the current method was called with a block passed to it.block_given?Step 2: Differentiate from other method checks
It does not check parameters, return values, or class definitions, only the presence of a block.Final Answer:
If a block was passed to the method -> Option DQuick Check:
block_given? checks block presence = A [OK]
- Confusing block_given? with method parameters
- Thinking it checks return values
- Assuming it checks class membership
Solution
Step 1: Identify correct method call syntax
block_given?is a method and should be called with a question mark and optionally parentheses. The most common and clear syntax isblock_given?without parentheses.Step 2: Confirm correct use of yield
Theyieldkeyword runs the block if it exists. The syntaxif block_given? then yield endis correct and clear.Final Answer:
if block_given? then yield end -> Option CQuick Check:
Correct syntax uses block_given? and yield [OK]
- Omitting question mark in block_given?
- Using block_given without parentheses incorrectly
- Calling yield with parentheses unnecessarily
def greet
if block_given?
yield
else
puts "Hello!"
end
end
greet { puts "Hi there!" }
greetSolution
Step 1: Analyze first greet call with block
The first call passes a block that prints "Hi there!". Since block_given? is true, yield runs the block, printing "Hi there!".Step 2: Analyze second greet call without block
The second call has no block, so block_given? is false and the else branch runs, printing "Hello!".Final Answer:
Hi there!\nHello! -> Option AQuick Check:
Block runs first, then default message = A [OK]
- Assuming yield runs even without block
- Thinking both calls print the same message
- Confusing order of outputs
def show
yield if block_given
end
show { puts "Hello!" }Solution
Step 1: Check block_given usage
The methodblock_given?requires the question mark and should be called asblock_given?orblock_given?(). Here it is missing the question mark.Step 2: Confirm yield usage
Theyieldis correctly used and does not require arguments here. The method does not require parameters to accept a block.Final Answer:
Missing question mark in block_given method call -> Option AQuick Check:
block_given? needs question mark [OK]
- Omitting question mark in block_given
- Thinking yield needs arguments always
- Assuming method needs parameters for blocks
process_items that takes an array and optionally a block. If a block is given, it should yield each item to the block; otherwise, it should return the array unchanged. Which code correctly implements this behavior?Solution
Step 1: Check block presence correctly
def process_items(arr) if block_given? arr.each { |item| yield item } else arr end end usesblock_given?correctly to check if a block is passed before yielding.Step 2: Handle both cases properly
If a block is given, it yields each item; otherwise, it returns the original array unchanged, matching the requirement.Step 3: Review other options for errors
def process_items(arr) arr.each { |item| yield item } end always yields without checking block presence, causing error if no block given. def process_items(arr) if block_given arr.each { |item| yield item } else arr end end misses question mark inblock_given. def process_items(arr) arr.each { |item| yield item if block_given? } end yields conditionally inside each, but block_given? inside the each block always returns false so no yielding occurs, though it returns the array.Final Answer:
def process_items(arr) if block_given? arr.each { |item| yield item } else arr end end -> Option BQuick Check:
Check block_given? before yield and return array if no block [OK]
- Not checking block_given? before yield
- Missing question mark in block_given
- Returning nil instead of array when no block
Ready to prove it?
Pass the test and this pattern moves unknown
