[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]