Project

General

Profile

Feature #14313

Support creating KeyError with receiver and key from Ruby

Added by kou (Kouhei Sutou) 20 days ago. Updated about 3 hours ago.

Status:
Open
Priority:
Normal
Target version:
-
[ruby-core:84626]

Description

KeyError has readers for error details, receiver and key. They are convenient to process KeyError.

We can set receiver and key to KeyError by rb_key_err_new() in C. But we can't set them in Ruby. Because receiver and key use no @ instance variables.

How about adding KeyError#initialize that accepts receiver and key? Because KeyError is useful in pure Ruby libraries. For example, csv library uses KeyError: https://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/csv.rb?revision=59849&view=markup#l321

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

I want to use KeyError for Hash like objects such as Arrow::Table in Red Arrow.

The attached patch adds KeyError#initialize that behaves as the following:

p KeyError.new.message
# => "KeyError": No change. Keep backward compatibility.

p KeyError.new("Message").message
# => "Message": No change. Keep backward compatibility.

p KeyError.new(receiver: Object.new).receiver
# => The Object instance.

p KeyError.new(key: :unknown_key).key
# => :unknown_key

key_error = KeyError.new(receiver: Object.new, key: :unknown_key)
p key_error.receiver
# => The Object instance.
p key_error.key
# => :unknown_key

key_error = KeyError.new("Message", receiver: Object.new, key: :unknown_key)
p key_error.message
# => "Message"
p key_error.receiver
# => The Object instance.
p key_error.key
# => :unknown_key
key_error_new.diff (2.91 KB) key_error_new.diff kou (Kouhei Sutou), 01/04/2018 04:58 AM

History

#1 [ruby-core:84635] Updated by nobu (Nobuyoshi Nakada) 19 days ago

Also NameError?

#2 [ruby-core:84637] Updated by Hanmac (Hans Mackowiak) 19 days ago

should that also extend to the raise function itself like this?

raise KeyError, "key not found: #{header}", key: :header

or is that already done?

#3 [ruby-core:84682] Updated by kou (Kouhei Sutou) 17 days ago

NameError already supports assigning name:

p NameError.new("message", :x).name # => :x

Ah, did you mention receiver not name?

#4 [ruby-core:84683] Updated by kou (Kouhei Sutou) 17 days ago

Kernel.#raise expects backtrace for the 3rd argument.
If we want to extend the current Kernel.#raise behavior, we should create a new issue instead of discussing in this issue.

#5 [ruby-core:85028] Updated by matz (Yukihiro Matsumoto) about 3 hours ago

I agree with the original proposal. We are not going to enhance raise behavior (yet).

Matz.

Also available in: Atom PDF