Holy Required Keyword Arguments Batman!

Hashes are a common data type passed to methods. Often times, methods that use hash arguments will need to verify if there are any missing keys. These checks require a lot of boilerplate code that can quickly become tedious to write and hard to maintain.


class Config
  def initialize(options)
    raise ArgumentError, 'missing keyword :url' if options[:url].nil?
    raise ArgumentError, 'missing keyword :ip' if options[:ip].nil?
    raise ArgumentError, 'missing keyword :port' if options[:port].nil?

    @url = options[:url]
    @ip = options[:ip]
    @port = options[:port]
  end
end

# This runs without error because all expected arguments are present
config = Config.new(url: 'google.com', ip: '127.0.0.1', port: 8080)

# This raises an ArgumentError due to missing hash key
config = Config.new(url: 'google.com')

Lucky for you, Ruby 2.1 introduced required keyword arguments which eliminates the need for all this extra code. Required keyword arguments look like normal arguments but with a trailing colon. If the hash passed to a method doesn't contain all the required keyword arguments, an ArgumentError will be raised.

class Config
  def initialize(url:, ip:, port:)
    @url = url
    @ip = ip
    @port = port
  end
end

# This runs without error because all expected arguments are present
config = Config.new(url: 'google.com', ip: '127.0.0.1', port: 8080)

# This also raises an ArgumentError due to missing hash key
config = Config.new(url: 'google.com')

No more hash key validation code required! Now you can focus on more important tasks, like whether or not to get that 5th cup of coffee. If you interested in some additional reading, check out Thoughtbot's Keywords Arguments article.