Feature #12041


Change the initializer of NameError to take a receiver as the third argument

Added by yuki24 (Yuki Nishijima) over 6 years ago. Updated over 6 years ago.

Target version:


I would like to change NameError#initialize to take a receiver object as the third argument. An example would be like this:

receiver_object =
name_error      ="Error message", "name", receiver_object)

name_error.receiver.equal?(receiver_object) # => true

The reason I wanted this change is Rails overrides Module#const_missing and raises an NameError without a receiver object. It has actually affected one of the did_you_mean's spell checkers and thus no suggestions for constant names will be made on Rails. One more use case I can think of is when there's a class that inherits from NameError or NoMethodError and an arbitrary receiver needs to be passed to the initializer of the class.

Please let me know if you have any thoughts.

Updated by nobu (Nobuyoshi Nakada) over 6 years ago

What's about NoMethodError?
Currently, it is, name [, args])  #-> no_method_error

If NameError#initialize has third argument, where will it be placed?

The last?, name [, args [,receiver]])  #-> no_method_error

or same as NameError#initialize?, name [, receiver [, args]])  #-> no_method_error

A patch for the latter.

diff --git i/error.c w/error.c
index f88c19a..0ae9b58 100644
--- i/error.c
+++ w/error.c
@@ -1127,7 +1127,7 @@ rb_name_error_str(VALUE str, const char *fmt, ...)
  * call-seq:
- * [, name])  -> name_error
+ * [, name [, receiver]])  -> name_error
  * Construct a new NameError exception. If given the <i>name</i>
  * parameter may subsequently be examined using the <code></code>
@@ -1138,8 +1138,10 @@ static VALUE
 name_err_initialize(int argc, VALUE *argv, VALUE self)
     VALUE name;
+    VALUE recv;
     VALUE iseqw = Qnil;
+    recv = (argc > 2) ? argv[--argc] : Qundef;
     name = (argc > 1) ? argv[--argc] : Qnil;
     rb_call_super(argc, argv);
     rb_ivar_set(self, id_name, name);
@@ -1150,6 +1152,7 @@ name_err_initialize(int argc, VALUE *argv, VALUE self)
 	if (cfp) iseqw = rb_iseqw_new(cfp->iseq);
     rb_ivar_set(self, id_iseq, iseqw);
+    if (recv != Qundef) rb_ivar_set(self, id_receiver, recv);
     return self;
@@ -1192,7 +1195,7 @@ name_err_local_variables(VALUE self)
  * call-seq:
- *, name [, args])  -> no_method_error
+ *, name [, receiver [, args]])  -> no_method_error
  * Construct a NoMethodError exception for a method of the given name
  * called with the given arguments. The name may be accessed using
diff --git i/test/ruby/test_exception.rb w/test/ruby/test_exception.rb
index 91732dd..e546988 100644
--- i/test/ruby/test_exception.rb
+++ w/test/ruby/test_exception.rb
@@ -699,6 +699,11 @@
     assert_same(obj, e.receiver)
     assert_equal(%i[a b c d e f g], e.local_variables.sort)
+    obj =
+    e ="error", :foo, obj)
+    assert_equal(:foo,
+    assert_same(obj, e.receiver)
   def test_name_error_info_parent_iseq_mark

Updated by yuki24 (Yuki Nishijima) over 6 years ago

Speaking of NoMethodError, I think the former (, name [, args [,receiver]])) makes more sense to me since the latter may break existing apps.

Updated by nobu (Nobuyoshi Nakada) over 6 years ago

Nobuyoshi Nakada wrote:

or same as NameError#initialize?, name [, receiver [, args]])  #-> no_method_error

This was wrong.
The previous patch is:, name [[, receiver], args])  #-> no_method_error

Updated by nobu (Nobuyoshi Nakada) over 6 years ago

I found this causes drb test failures, since NoMethodError now refers DRbObject and Marshal.dump fails.


Also available in: Atom PDF