ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:68515] [Ruby trunk - Bug #10969] [Open] public_send in combination with method_missing raises NameError instead of NoMethodError
       [not found] <redmine.issue-10969.20150313081846@ruby-lang.org>
@ 2015-03-13  8:18 ` yves.senn
  2015-07-29  6:37 ` [ruby-core:70165] [Ruby trunk - Bug #10969] " nobu
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 4+ messages in thread
From: yves.senn @ 2015-03-13  8:18 UTC (permalink / raw
  To: ruby-core

Issue #10969 has been reported by Yves Senn.

----------------------------------------
Bug #10969: public_send in combination with method_missing raises NameError instead of NoMethodError
https://bugs.ruby-lang.org/issues/10969

* Author: Yves Senn
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-darwin14]
* Backport: 
----------------------------------------
While working on the Rails project, specifically this issue https://github.com/rails/rails/issues/19297 I discovered that `public_send` can raise a `NameError` instead of a `NoMethodError`.

Following is a minimal reproduction scenario to trigger the bug. A more detailed example can be found in this Gist: https://gist.github.com/senny/9864a138defa322ed807

~~~
class Person
  def implicit_assignment
    nope rescue nil
    public_send "nope="
  end

  def method_missing(*args)
    super
  end
end

a = Person.new
a.implicit_assignment
# test.rb:13:in `method_missing': undefined local variable or method `nope=' for #<Person:0x007f91d1052ef8> (NameError)
# 	from test.rb:4:in `public_send'
# 	from test.rb:4:in `implicit_assignment'
# 	from test.rb:24:in `<main>'
~~~

### What a found out during debugging:

I am not a C programmer and have very little experience in that field. While debugging the issue I could make some observations what's going on.

The error is being raised in `raise_method_missing` (https://github.com/ruby/ruby/blob/7790f37efdd8dd42a0a43c3206f6afdd43f8e86a/vm_eval.c#L704-L706):

~~~
else if (last_call_status & NOEX_VCALL) {
  format = "undefined local variable or method `%s' for %s";
  exc = rb_eNameError;
~~~

`last_call_status` is stored on the current thread (https://github.com/ruby/ruby/blob/7790f37efdd8dd42a0a43c3206f6afdd43f8e86a/vm_eval.c#L655):

The thread struct is modified in `vm_call_method_missing` (https://github.com/ruby/ruby/blob/7790f37efdd8dd42a0a43c3206f6afdd43f8e86a/vm_insnhelper.c#L1668):

~~~
th->method_missing_reason = ci->aux.missing_reason;
~~~

Now the problem is, that the call to `public_send` with the method name containing an `=` sign, does not modify the thread struct. This means that it still contains the value assigned from the previous call. That's what `nope rescue nil` in the reproduction is used for. It assigns `NOEX_VCALL` to that struct.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-core:70165] [Ruby trunk - Bug #10969] public_send in combination with method_missing raises NameError instead of NoMethodError
       [not found] <redmine.issue-10969.20150313081846@ruby-lang.org>
  2015-03-13  8:18 ` [ruby-core:68515] [Ruby trunk - Bug #10969] [Open] public_send in combination with method_missing raises NameError instead of NoMethodError yves.senn
@ 2015-07-29  6:37 ` nobu
  2015-07-30 10:45 ` [ruby-core:70189] " yves.senn
  2015-11-27 21:09 ` [ruby-core:71711] " nagachika00
  3 siblings, 0 replies; 4+ messages in thread
From: nobu @ 2015-07-29  6:37 UTC (permalink / raw
  To: ruby-core

Issue #10969 has been updated by Nobuyoshi Nakada.

Description updated
Backport set to 2.0.0: DONTNEED, 2.1: DONTNEED, 2.2: REQUIRED

----------------------------------------
Bug #10969: public_send in combination with method_missing raises NameError instead of NoMethodError
https://bugs.ruby-lang.org/issues/10969#change-53593

* Author: Yves Senn
* Status: Closed
* Priority: Normal
* Assignee: 
* ruby -v: ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-darwin14]
* Backport: 2.0.0: DONTNEED, 2.1: DONTNEED, 2.2: REQUIRED
----------------------------------------
While working on the Rails project, specifically this issue https://github.com/rails/rails/issues/19297 I discovered that `public_send` can raise a `NameError` instead of a `NoMethodError`.

Following is a minimal reproduction scenario to trigger the bug. A more detailed example can be found in this Gist: https://gist.github.com/senny/9864a138defa322ed807

~~~ruby
class Person
  def implicit_assignment
    nope rescue nil
    public_send "nope="
  end

  def method_missing(*args)
    super
  end
end

a = Person.new
a.implicit_assignment
# test.rb:13:in `method_missing': undefined local variable or method `nope=' for #<Person:0x007f91d1052ef8> (NameError)
# 	from test.rb:4:in `public_send'
# 	from test.rb:4:in `implicit_assignment'
# 	from test.rb:24:in `<main>'
~~~

### What a found out during debugging:

I am not a C programmer and have very little experience in that field. While debugging the issue I could make some observations what's going on.

The error is being raised in `raise_method_missing` (https://github.com/ruby/ruby/blob/7790f37efdd8dd42a0a43c3206f6afdd43f8e86a/vm_eval.c#L704-L706):

~~~c
else if (last_call_status & NOEX_VCALL) {
  format = "undefined local variable or method `%s' for %s";
  exc = rb_eNameError;
~~~

`last_call_status` is stored on the current thread (https://github.com/ruby/ruby/blob/7790f37efdd8dd42a0a43c3206f6afdd43f8e86a/vm_eval.c#L655):

The thread struct is modified in `vm_call_method_missing` (https://github.com/ruby/ruby/blob/7790f37efdd8dd42a0a43c3206f6afdd43f8e86a/vm_insnhelper.c#L1668):

~~~c
th->method_missing_reason = ci->aux.missing_reason;
~~~

Now the problem is, that the call to `public_send` with the method name containing an `=` sign, does not modify the thread struct. This means that it still contains the value assigned from the previous call. That's what `nope rescue nil` in the reproduction is used for. It assigns `NOEX_VCALL` to that struct.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-core:70189] [Ruby trunk - Bug #10969] public_send in combination with method_missing raises NameError instead of NoMethodError
       [not found] <redmine.issue-10969.20150313081846@ruby-lang.org>
  2015-03-13  8:18 ` [ruby-core:68515] [Ruby trunk - Bug #10969] [Open] public_send in combination with method_missing raises NameError instead of NoMethodError yves.senn
  2015-07-29  6:37 ` [ruby-core:70165] [Ruby trunk - Bug #10969] " nobu
@ 2015-07-30 10:45 ` yves.senn
  2015-11-27 21:09 ` [ruby-core:71711] " nagachika00
  3 siblings, 0 replies; 4+ messages in thread
From: yves.senn @ 2015-07-30 10:45 UTC (permalink / raw
  To: ruby-core

Issue #10969 has been updated by Yves Senn.


Thank you Nobuyoshi Nakada and Koichi Sasada! 💛

----------------------------------------
Bug #10969: public_send in combination with method_missing raises NameError instead of NoMethodError
https://bugs.ruby-lang.org/issues/10969#change-53616

* Author: Yves Senn
* Status: Closed
* Priority: Normal
* Assignee: 
* ruby -v: ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-darwin14]
* Backport: 2.0.0: DONTNEED, 2.1: DONTNEED, 2.2: REQUIRED
----------------------------------------
While working on the Rails project, specifically this issue https://github.com/rails/rails/issues/19297 I discovered that `public_send` can raise a `NameError` instead of a `NoMethodError`.

Following is a minimal reproduction scenario to trigger the bug. A more detailed example can be found in this Gist: https://gist.github.com/senny/9864a138defa322ed807

~~~ruby
class Person
  def implicit_assignment
    nope rescue nil
    public_send "nope="
  end

  def method_missing(*args)
    super
  end
end

a = Person.new
a.implicit_assignment
# test.rb:13:in `method_missing': undefined local variable or method `nope=' for #<Person:0x007f91d1052ef8> (NameError)
# 	from test.rb:4:in `public_send'
# 	from test.rb:4:in `implicit_assignment'
# 	from test.rb:24:in `<main>'
~~~

### What a found out during debugging:

I am not a C programmer and have very little experience in that field. While debugging the issue I could make some observations what's going on.

The error is being raised in `raise_method_missing` (https://github.com/ruby/ruby/blob/7790f37efdd8dd42a0a43c3206f6afdd43f8e86a/vm_eval.c#L704-L706):

~~~c
else if (last_call_status & NOEX_VCALL) {
  format = "undefined local variable or method `%s' for %s";
  exc = rb_eNameError;
~~~

`last_call_status` is stored on the current thread (https://github.com/ruby/ruby/blob/7790f37efdd8dd42a0a43c3206f6afdd43f8e86a/vm_eval.c#L655):

The thread struct is modified in `vm_call_method_missing` (https://github.com/ruby/ruby/blob/7790f37efdd8dd42a0a43c3206f6afdd43f8e86a/vm_insnhelper.c#L1668):

~~~c
th->method_missing_reason = ci->aux.missing_reason;
~~~

Now the problem is, that the call to `public_send` with the method name containing an `=` sign, does not modify the thread struct. This means that it still contains the value assigned from the previous call. That's what `nope rescue nil` in the reproduction is used for. It assigns `NOEX_VCALL` to that struct.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-core:71711] [Ruby trunk - Bug #10969] public_send in combination with method_missing raises NameError instead of NoMethodError
       [not found] <redmine.issue-10969.20150313081846@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2015-07-30 10:45 ` [ruby-core:70189] " yves.senn
@ 2015-11-27 21:09 ` nagachika00
  3 siblings, 0 replies; 4+ messages in thread
From: nagachika00 @ 2015-11-27 21:09 UTC (permalink / raw
  To: ruby-core

Issue #10969 has been updated by Tomoyuki Chikanaga.

Backport changed from 2.0.0: DONTNEED, 2.1: DONTNEED, 2.2: REQUIRED to 2.0.0: DONTNEED, 2.1: DONTNEED, 2.2: DONE

Backported into `ruby_2_2` branch at r52771.
The `MISSING_NOENTRY` was introduced at r50743. I replaced `MISSING_NOENTRY` it to `0` to backport.

----------------------------------------
Bug #10969: public_send in combination with method_missing raises NameError instead of NoMethodError
https://bugs.ruby-lang.org/issues/10969#change-55117

* Author: Yves Senn
* Status: Closed
* Priority: Normal
* Assignee: 
* ruby -v: ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-darwin14]
* Backport: 2.0.0: DONTNEED, 2.1: DONTNEED, 2.2: DONE
----------------------------------------
While working on the Rails project, specifically this issue https://github.com/rails/rails/issues/19297 I discovered that `public_send` can raise a `NameError` instead of a `NoMethodError`.

Following is a minimal reproduction scenario to trigger the bug. A more detailed example can be found in this Gist: https://gist.github.com/senny/9864a138defa322ed807

~~~ruby
class Person
  def implicit_assignment
    nope rescue nil
    public_send "nope="
  end

  def method_missing(*args)
    super
  end
end

a = Person.new
a.implicit_assignment
# test.rb:13:in `method_missing': undefined local variable or method `nope=' for #<Person:0x007f91d1052ef8> (NameError)
# 	from test.rb:4:in `public_send'
# 	from test.rb:4:in `implicit_assignment'
# 	from test.rb:24:in `<main>'
~~~

### What a found out during debugging:

I am not a C programmer and have very little experience in that field. While debugging the issue I could make some observations what's going on.

The error is being raised in `raise_method_missing` (https://github.com/ruby/ruby/blob/7790f37efdd8dd42a0a43c3206f6afdd43f8e86a/vm_eval.c#L704-L706):

~~~c
else if (last_call_status & NOEX_VCALL) {
  format = "undefined local variable or method `%s' for %s";
  exc = rb_eNameError;
~~~

`last_call_status` is stored on the current thread (https://github.com/ruby/ruby/blob/7790f37efdd8dd42a0a43c3206f6afdd43f8e86a/vm_eval.c#L655):

The thread struct is modified in `vm_call_method_missing` (https://github.com/ruby/ruby/blob/7790f37efdd8dd42a0a43c3206f6afdd43f8e86a/vm_insnhelper.c#L1668):

~~~c
th->method_missing_reason = ci->aux.missing_reason;
~~~

Now the problem is, that the call to `public_send` with the method name containing an `=` sign, does not modify the thread struct. This means that it still contains the value assigned from the previous call. That's what `nope rescue nil` in the reproduction is used for. It assigns `NOEX_VCALL` to that struct.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-11-27 20:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <redmine.issue-10969.20150313081846@ruby-lang.org>
2015-03-13  8:18 ` [ruby-core:68515] [Ruby trunk - Bug #10969] [Open] public_send in combination with method_missing raises NameError instead of NoMethodError yves.senn
2015-07-29  6:37 ` [ruby-core:70165] [Ruby trunk - Bug #10969] " nobu
2015-07-30 10:45 ` [ruby-core:70189] " yves.senn
2015-11-27 21:09 ` [ruby-core:71711] " nagachika00

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).