Today I Learned

A Hashrocket project

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'

def do_block_stuff_by_val
  company_name = 'hash'
  puts company_name #prints 'hash', not 'hashrocket'

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'

def do_block_stuff_by_object_reference
  company = {}
  puts company # { name: 'hashrocket'}
Looking for help? Each developer at Hashrocket has years of experience working with Ruby applications of all types and sizes. Contact us and find out how we can help you.