Project

General

Profile

Actions

Feature #14313

closed

Support creating KeyError with receiver and key from Ruby

Feature #14313: Support creating KeyError with receiver and key from Ruby

Added by kou (Kouhei Sutou) almost 8 years ago. Updated almost 8 years ago.

Status:
Closed
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 

Files

key_error_new.diff (2.91 KB) key_error_new.diff kou (Kouhei Sutou), 01/04/2018 04:58 AM

Related issues 1 (0 open1 closed)

Updated by nobu (Nobuyoshi Nakada) almost 8 years ago Actions #1 [ruby-core:84635]

Also NameError?

Updated by Hanmac (Hans Mackowiak) almost 8 years ago Actions #2 [ruby-core:84637]

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

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

or is that already done?

Updated by kou (Kouhei Sutou) almost 8 years ago Actions #3 [ruby-core:84682]

NameError already supports assigning name:

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

Ah, did you mention receiver not name?

Updated by kou (Kouhei Sutou) almost 8 years ago Actions #4 [ruby-core:84683]

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.

Updated by matz (Yukihiro Matsumoto) almost 8 years ago Actions #5 [ruby-core:85028]

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

Matz.

Updated by kou (Kouhei Sutou) almost 8 years ago Actions #6

  • Status changed from Open to Closed

Applied in changeset trunk|r62049.


KeyError#initialize accepts receiver and key.
[Feature #14313][ruby-core:84626]

Updated by nobu (Nobuyoshi Nakada) almost 8 years ago Actions #7 [ruby-core:85127]

Shouldn't unspecified attribute raise an exception?

diff --git c/error.c i/error.c index 990f9f7855..7870e58035 100644 --- c/error.c +++ i/error.c @@ -1692,8 +1692,6 @@ key_err_initialize(int argc, VALUE *argv, VALUE self) { VALUE message; VALUE options; - VALUE receiver = Qnil; - VALUE key = Qnil;  rb_scan_args(argc, argv, "01:", &message, &options); @@ -1711,16 +1709,13 @@ key_err_initialize(int argc, VALUE *argv, VALUE self)	keywords[1] = id_key;	rb_get_kwargs(options, keywords, 0, 2, values);	if (values[0] != Qundef) { - receiver = values[0]; + rb_ivar_set(self, id_receiver, values[0]); 	}	if (values[1] != Qundef) { - key = values[1]; + rb_ivar_set(self, id_key, values[1]); 	} } - rb_ivar_set(self, id_receiver, receiver); - rb_ivar_set(self, id_key, key); -  return self; } diff --git c/test/ruby/test_key_error.rb i/test/ruby/test_key_error.rb index 852bd32712..fe1d5bb5ab 100644 --- c/test/ruby/test_key_error.rb +++ i/test/ruby/test_key_error.rb @@ -15,11 +15,15 @@ receiver = Object.new error = KeyError.new(receiver: receiver) assert_equal(receiver, error.receiver) + error = KeyError.new + assert_raise(ArgumentError) {error.receiver}  end def test_key error = KeyError.new(key: :key) assert_equal(:key, error.key) + error = KeyError.new + assert_raise(ArgumentError) {error.key}  end def test_receiver_and_key 

Updated by nobu (Nobuyoshi Nakada) over 7 years ago Actions #8

  • Related to Bug #14670: Objectで定義したmethod_missingでsuperが使えない added
Actions

Also available in: PDF Atom