Feature #14313
closedSupport creating KeyError with receiver and key from Ruby
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
Updated by nobu (Nobuyoshi Nakada) almost 8 years ago
Also NameError?
Updated by Hanmac (Hans Mackowiak) almost 8 years 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?
Updated by kou (Kouhei Sutou) almost 8 years ago
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
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
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
- 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
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
- Related to Bug #14670: Objectで定義したmethod_missingでsuperが使えない added