Ruby Object Reference in blocks
Usually when I want to set the value of a variable by yielding to a block, I will explicity set it
x = 'something'
x = yield(x)
#....
Turns out ruby will treat different types of objects different when yielded to a block (remember everything is an object). If you are yielding an Integer, or String for (a contrived) example:
def do_stuff_by_val
do_block_stuff_by_val do |name|
name += 'rocket'
end
end
def do_block_stuff_by_val
company_name = 'hash'
yield(company_name)
puts company_name #prints 'hash', not 'hashrocket'
end
If we wanted the company name to change to "hashrocket", we would need to explicitly set the variable to the result of yielding:
company_name = yield(company_name)
Other types of objects do not behave this way (hash or array). If we yield a hash and set a key, the hash in the calling method will be updated:
def do_stuff_by_object_reference
do_block_stuff_by_object_reference do |company|
company[:name] = 'hashrocket'
end
end
def do_block_stuff_by_object_reference
company = {}
yield(company)
puts company # { name: 'hashrocket'}
end
Tweet