Reputation: 3738
For the life of me, I can't figure out why this doesn't work as expected.
Code:
require 'erb'
def say_hello(name)
"Nice to see you, #{ name }!"
end
def greetings
template = <<-TEMPLATE
Hello!
<%= yield %>
Goodbye!
TEMPLATE
ERB.new(template).result(binding)
end
people = ['Aaron', 'Bob', 'Tim', 'Juan']
t = greetings do
people.each do |p|
say_hello(p)
end
end
puts t
(a bit contrived, I know, but it'll serve the point.)
What I Expect:
Hello!
Nice to see you, Aaron!
Nice to see you, Bob!
Nice to see you, Tim!
Nice to see you, Juan!
Goodbye!
What I Get:
Hello!
['Aaron', 'Bob', 'Tim', 'Juan']
Goodbye!
Thoughts:
I'm guessing this is happening because the interior block (beginning with people.each
) gets coerced into a string before the block executes. Perhaps ERB doesn't like how I'm trying to inject a new block of constructed text into its template.
What's going on here?
Upvotes: 0
Views: 373
Reputation: 37409
The return value of each
is the array itself, not the return value of the block:
people.each do |p|
say_hello(p)
end
# => ['Aaron', 'Bob', 'Tim', 'Juan']
You should use map
, which returns the array of return values from the block:
people.map do |p|
say_hello(p)
end
# => ["Nice to see you, Aaron!", "Nice to see you, Bob!", "Nice to see you, Tim!", "Nice to see you, Juan!"]
You will also need to concatenate the array to render it properly:
t = greetings do
people.map do |p|
say_hello(p)
end.join("\n")
end
Upvotes: 2