DEV Community

Akshay Khot
Akshay Khot

Posted on • Originally published at

How to Access Hash Values Like Methods in Ruby

In Ruby, if you want to access hash values like methods on an object, use ActiveSupport::OrderedOptions. This class inherits from Hash and provides dynamic accessor methods.

Typically, you'd do this with a Hash.

person = {
    name: "Jason",
    company: "Basecamp"

person[:company] # 'Basecamp'
Enter fullscreen mode Exit fullscreen mode

Using OrderedOptions, you can write

require "active_support/ordered_options"

person =

# set the values = "Jason" = "Basecamp"

# access the values  # => 'Jason' # => 'Basecamp'
Enter fullscreen mode Exit fullscreen mode


Behind the scenes, Rails implements this feature using metaprogramming in Ruby. It uses the method_missing method to handle the method call.

def method_missing(name, *args)
  name_string = +name.to_s
  if name_string.chomp!("=")
    self[name_string] = args.first   # set the value
    bangs = name_string.chomp!("!")

    # get the value
    if bangs
      self[name_string].presence || raise(":#{name_string} is blank"))
Enter fullscreen mode Exit fullscreen mode

You can read the complete source code here. For more details on metaprogramming in Ruby, read my notes of the Metaprogramming Ruby 2 book.

Real-World Usage

Propshaft is an asset pipeline library for Rails. It uses OrderedOptions to define the config.assets settings, instead of creating a new configuration object. You can read the complete source on Github.

class Railtie < ::Rails::Railtie
    config.assets =

    config.assets.paths          = []
    config.assets.excluded_paths = []
    config.assets.version        = "1"
    config.assets.prefix         = "/assets"
Enter fullscreen mode Exit fullscreen mode

Now, this doesn't mean you have to replace all your hashes with instances of OrderedOptions. It's better to use them with configuration-like objects, which often results in more readable code.

Hope that helps. Let me know what you think about this approach.

Top comments (3)

jeremyf profile image
Jeremy Friesen

I wasn't aware of this class; thank you for sharing. In the past I'd used (and removed) OpenStruct.

software_writer profile image
Akshay Khot

Thanks, Leonid!