Project

General

Profile

Feature #14313

Support creating KeyError with receiver and key from Ruby

Added by kou (Kouhei Sutou) 11 months ago. Updated 11 months ago.

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

Related issues

Related to Ruby trunk - Bug #14670: Objectで定義したmethod_missingでsuperが使えないClosed

Associated revisions

Revision cd83d267
Added by kou (Kouhei Sutou) 11 months ago

KeyError#initialize accepts receiver and key.
[Feature #14313]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62049 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 62049
Added by kou (Kouhei Sutou) 11 months ago

KeyError#initialize accepts receiver and key.
[Feature #14313]

Revision b56f6a6b
Added by nobu (Nobuyoshi Nakada) 11 months ago

error.c: use already initialized IDs
[Feature #14313]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62050 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 62050
Added by nobu (Nobuyoshi Nakada) 11 months ago

error.c: use already initialized IDs
[Feature #14313]

Revision ba4aba0d
Added by nobu (Nobuyoshi Nakada) 11 months ago

error.c: KeyError missing keyword arguments

  • error.c (key_err_initialize): leave attributes for missing keyword arguments unset, so accessors can tell if it is missing or explicit nil. [Feature #14313]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62053 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 62053
Added by nobu (Nobuyoshi Nakada) 11 months ago

error.c: KeyError missing keyword arguments

  • error.c (key_err_initialize): leave attributes for missing keyword arguments unset, so accessors can tell if it is missing or explicit nil. [Feature #14313]

Revision 98c88786
Added by nobu (Nobuyoshi Nakada) 11 months ago

error.c: copy keyword arguments

  • error.c (rb_key_err_new): pass arguments all arguments to the super method, except for keyword arguments copied to instance variables. [Feature #14313]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62054 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 62054
Added by nobu (Nobuyoshi Nakada) 11 months ago

error.c: copy keyword arguments

  • error.c (rb_key_err_new): pass arguments all arguments to the super method, except for keyword arguments copied to instance variables. [Feature #14313]

Revision c30aed08
Added by nobu (Nobuyoshi Nakada) 11 months ago

error.c: receiver kwarg

  • error.c (name_err_initialize_options): NameError#initialize
    accepts receiver. [Feature #14313]

  • error.c (nometh_err_initialize_options): pass keyword arguments
    to the super method.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62057 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 62057
Added by nobu (Nobuyoshi Nakada) 11 months ago

error.c: receiver kwarg

  • error.c (name_err_initialize_options): NameError#initialize
    accepts receiver. [Feature #14313]

  • error.c (nometh_err_initialize_options): pass keyword arguments
    to the super method.

History

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

Also NameError?

#2 [ruby-core:84637] Updated by Hanmac (Hans Mackowiak) 11 months 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) 11 months 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) 11 months 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) 11 months ago

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

Matz.

#6 Updated by kou (Kouhei Sutou) 11 months ago

  • Status changed from Open to Closed

Applied in changeset trunk|r62049.


KeyError#initialize accepts receiver and key.
[Feature #14313]

#7 [ruby-core:85127] Updated by nobu (Nobuyoshi Nakada) 11 months ago

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

#8 Updated by nobu (Nobuyoshi Nakada) 8 months ago

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

Also available in: Atom PDF