From: nobu@... Date: 2016-02-01T12:25:22+00:00 Subject: [ruby-core:73631] [Ruby trunk Feature#12041]Change the initializer of NameError to take a receiver as the third argument Issue #12041 has been updated by Nobuyoshi Nakada. What's about `NoMethodError`? Currently, it is ```ruby NoMethodError.new(msg, name [, args]) #-> no_method_error ``` If `NameError#initialize` has third argument, where will it be placed? The last? ```ruby NoMethodError.new(msg, name [, args [,receiver]]) #-> no_method_error ``` or same as `NameError#initialize`? ```ruby NoMethodError.new(msg, name [, receiver [, args]]) #-> no_method_error ``` A patch for the latter. ```diff 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: - * NameError.new(msg [, name]) -> name_error + * NameError.new(msg [, name [, receiver]]) -> name_error * * Construct a new NameError exception. If given the name * parameter may subsequently be examined using the NameError.name @@ -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: - * NoMethodError.new(msg, name [, args]) -> no_method_error + * NoMethodError.new(msg, 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_equal(:foo, e.name) assert_same(obj, e.receiver) assert_equal(%i[a b c d e f g], e.local_variables.sort) + + obj = Object.new + e = NameError.new("error", :foo, obj) + assert_equal(:foo, e.name) + assert_same(obj, e.receiver) end def test_name_error_info_parent_iseq_mark ``` ---------------------------------------- Feature #12041: Change the initializer of NameError to take a receiver as the third argument https://bugs.ruby-lang.org/issues/12041#change-56824 * Author: Yuki Nishijima * Status: Open * Priority: Normal * Assignee: ---------------------------------------- I would like to change `NameError#initialize` to take a receiver object as the third argument. An example would be like this: ```ruby receiver_object = Object.new name_error = NameError.new("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](https://github.com/rails/rails/blob/23b6f65/activesupport/lib/active_support/dependencies.rb#L567-L569). 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. -- https://bugs.ruby-lang.org/ Unsubscribe: