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 7 years ago
Also NameError
?
Updated by Hanmac (Hans Mackowiak) almost 7 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 7 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 7 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 7 years ago
I agree with the original proposal. We are not going to enhance raise
behavior (yet).
Matz.
Updated by kou (Kouhei Sutou) almost 7 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 7 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 6 years ago
- Related to Bug #14670: Objectで定義したmethod_missingでsuperが使えない added