Ruby 2.6 KeyError#initialize accepts message, receiver, and key as arguments

Atul Bhosale's avatar

Atul Bhosale

Ruby 2.6.0-preview2 was recently released.

Ruby 2.5.0 introduced public instance methods KeyError#key and KeyError#receiver. You can read my earlier blog about KeyError#key & KeyError#receiver here.

Ruby csv library raises a KeyError on CSV::Row#fetch method when the field is not found.

def fetch(header, *varargs)
  # ...
  raise KeyError, "key not found: #{header}"
  # ...

Instead of raising a KeyError shown above, how about if this is possible? -

raise KeyError.new("key not found", key: header)

with this we can check the KeyError object for the error message and key using KeyError#message and KeyError#key methods which were introduced in Ruby 2.5.0.

  raise KeyError.new('key not found', key: :unknown)
rescue StandardError => error
  p error.message #=> "key not found"
  p error.key #=> :unknown

It was proposed that KeyError#initialize method should be introduced which accepts message, receiver and key as arguments to set them on a KeyError object and it was approved.

Ruby 2.6.0

In Ruby 2.6.0 KeyError#initialize accepts message, receiver, and key as arguments, where the message is a default argument with default value as nil.


>> error = KeyError.new
=> #<KeyError: KeyError>


>> error.message
=> "KeyError"
>> error = KeyError.new('Message')
=> #<KeyError: Message>
>> error.message
=> "Message"

When message is not passed to KeyError it sets the class name as the message.

KeyError#initialize with message, :receiver and :key

>> error = KeyError.new('Message', receiver: Object.new, key: :unknown)
=> #<KeyError: Message>
>> error.message
=> "Message"
>> error.receiver
=> #<Object:0x0000561132683d48>
>> error.key
=> :unknown

I hope these method arguments for KeyError class are useful in your future debugging attempts.