Atul Bhosale

14 Aug 2018

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

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}"
    # ...
  end

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.

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

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.

KeyError#initialize

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

KeyError#message

  >> 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.

Tags

comments powered by Disqus