Reputation: 89
I am new to the concept of yield and currently practising it.
I was expecting to get ["bread", "JUICY", "bread"]
but I got ["bread", "steak", "bread"]
.
Can you please help me understand why? And how can I fix my code?
def burger(patty)
if block_given?
yield(patty)
end
return ["bread", patty, "bread"]
end
# TODO: Change 'steak'to 'JUICY'using yield
juicy_burger = burger("steak") do |patty|
patty = "JUICY"
end
p juicy_burger
Upvotes: 2
Views: 1153
Reputation: 2066
The variable is local to the function and you did not save back the value yield returned. The code below will give you ["bread", "JUICY", "bread"]
def burger(patty)
if block_given?
patty = yield(patty) # <-- this is the diff
end
return ["bread", patty, "bread"]
end
# TODO: Change 'steak'to 'JUICY'using yield
juicy_burger = burger("steak") do |patty|
patty = "JUICY"
end
p juicy_burger
Upvotes: 1
Reputation: 230336
juicy_burger = burger("steak") do |patty| patty = "JUICY" end
Reassignments like this are not propagated to the outer scopes. Once this block returns, patty
"reverts" to its initial value.
Solution? Use the overwritten value while it's still in scope.
def burger(patty)
if block_given?
patty = yield(patty)
# ^ shadow the parameter here.
# doesn't have to be a shadow. You can use any name. new_patty = yield(patty)
end
return ["bread", patty, "bread"]
end
juicy_burger = burger("steak") do |patty|
"JUICY #{patty}" # <- simple return here
end
p juicy_burger # >> ["bread", "JUICY steak", "bread"]
Upvotes: 3