ruby-changes:49939
From: nobu <ko1@a...>
Date: Fri, 26 Jan 2018 20:02:48 +0900 (JST)
Subject: [ruby-changes:49939] nobu:r62057 (trunk): error.c: receiver kwarg
nobu 2018-01-26 19:55:47 +0900 (Fri, 26 Jan 2018) New Revision: 62057 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62057 Log: 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. Modified files: trunk/error.c trunk/test/ruby/test_exception.rb Index: error.c =================================================================== --- error.c (revision 62056) +++ error.c (revision 62057) @@ -1351,6 +1351,8 @@ rb_name_error_str(VALUE str, const char https://github.com/ruby/ruby/blob/trunk/error.c#L1351 rb_exc_raise(exc); } +static VALUE name_err_initialize_options(int argc, VALUE *argv, VALUE self, VALUE options); + /* * call-seq: * NameError.new([msg, *, name]) -> name_error @@ -1363,12 +1365,30 @@ rb_name_error_str(VALUE str, const char https://github.com/ruby/ruby/blob/trunk/error.c#L1365 static VALUE name_err_initialize(int argc, VALUE *argv, VALUE self) { + VALUE options; + argc = rb_scan_args(argc, argv, "*:", NULL, &options); + return name_err_initialize_options(argc, argv, self, options); +} + +static VALUE +name_err_initialize_options(int argc, VALUE *argv, VALUE self, VALUE options) +{ + ID keywords[1]; + VALUE values[numberof(keywords)]; VALUE name; VALUE iseqw = Qnil; + int i; + keywords[0] = id_receiver; + rb_get_kwargs(options, keywords, 0, numberof(values), values); name = (argc > 1) ? argv[--argc] : Qnil; rb_call_super(argc, argv); rb_ivar_set(self, id_name, name); + for (i = 0; i < numberof(keywords); ++i) { + if (values[i] != Qundef) { + rb_ivar_set(self, keywords[i], values[i]); + } + } { const rb_execution_context_t *ec = GET_EC(); rb_control_frame_t *cfp = @@ -1416,6 +1436,8 @@ name_err_local_variables(VALUE self) https://github.com/ruby/ruby/blob/trunk/error.c#L1436 return vars; } +static VALUE nometh_err_initialize_options(int argc, VALUE *argv, VALUE self, VALUE options); + /* * call-seq: * NoMethodError.new([msg, *, name [, args [, priv]]]) -> no_method_error @@ -1429,9 +1451,17 @@ name_err_local_variables(VALUE self) https://github.com/ruby/ruby/blob/trunk/error.c#L1451 static VALUE nometh_err_initialize(int argc, VALUE *argv, VALUE self) { + VALUE options; + argc = rb_scan_args(argc, argv, "*:", NULL, &options); + return nometh_err_initialize_options(argc, argv, self, options); +} + +static VALUE +nometh_err_initialize_options(int argc, VALUE *argv, VALUE self, VALUE options) +{ VALUE priv = (argc > 3) && (--argc, RTEST(argv[argc])) ? Qtrue : Qfalse; VALUE args = (argc > 2) ? argv[--argc] : Qnil; - name_err_initialize(argc, argv, self); + name_err_initialize_options(argc, argv, self, options); rb_ivar_set(self, id_args, args); rb_ivar_set(self, id_private_call_p, RTEST(priv) ? Qtrue : Qfalse); return self; Index: test/ruby/test_exception.rb =================================================================== --- test/ruby/test_exception.rb (revision 62056) +++ test/ruby/test_exception.rb (revision 62057) @@ -866,6 +866,14 @@ end.join https://github.com/ruby/ruby/blob/trunk/test/ruby/test_exception.rb#L866 error = NameError.new assert_raise(ArgumentError) {error.receiver} assert_equal("NameError", error.message) + + error = NameError.new(receiver: receiver) + assert_equal(["NameError", receiver], + [error.message, error.receiver]) + + error = NameError.new("Message", :foo, receiver: receiver) + assert_equal(["Message", receiver, :foo], + [error.message, error.receiver, error.name]) end def test_nomethod_error_new_default @@ -903,6 +911,44 @@ end.join https://github.com/ruby/ruby/blob/trunk/test/ruby/test_exception.rb#L911 [error.name, error.args, error.private_call?]) end + def test_nomethod_error_new_receiver + receiver = Object.new + + error = NoMethodError.new + assert_raise(ArgumentError) {error.receiver} + + error = NoMethodError.new(receiver: receiver) + assert_equal(receiver, error.receiver) + + error = NoMethodError.new("Message") + assert_raise(ArgumentError) {error.receiver} + + error = NoMethodError.new("Message", receiver: receiver) + assert_equal(["Message", receiver], + [error.message, error.receiver]) + + error = NoMethodError.new("Message", :foo) + assert_raise(ArgumentError) {error.receiver} + + error = NoMethodError.new("Message", :foo, receiver: receiver) + assert_equal(["Message", :foo, receiver], + [error.message, error.name, error.receiver]) + + error = NoMethodError.new("Message", :foo, [1, 2]) + assert_raise(ArgumentError) {error.receiver} + + error = NoMethodError.new("Message", :foo, [1, 2], receiver: receiver) + assert_equal(["Message", :foo, [1, 2], receiver], + [error.message, error.name, error.args, error.receiver]) + + error = NoMethodError.new("Message", :foo, [1, 2], true) + assert_raise(ArgumentError) {error.receiver} + + error = NoMethodError.new("Message", :foo, [1, 2], true, receiver: receiver) + assert_equal([:foo, [1, 2], true, receiver], + [error.name, error.args, error.private_call?, error.receiver]) + end + def test_name_error_info_const obj = PrettyObject.new -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/