Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NameError is thrown by method_missing when using self #872

Closed
andrenpaes opened this Issue Jul 10, 2013 · 4 comments

Comments

Projects
None yet
3 participants
@andrenpaes
Copy link

andrenpaes commented Jul 10, 2013

The method_missing method is throwing the NameError exception instead of NoMethodError when using self as the message receiver.

Here's an example

class Bug
  def method_missing(meth, *args, &block)
    super
  rescue NoMethodError
    puts "Catched Error!"
    args.first
  end

  def set_bug_type
    self.bug_type = 2
  end
end

Bug.new.bug_type = 1
Bug.new.set_bug_type

The expected output is (that's what I get in MRI 1.9.x):

Catched Error!
Catched Error!

The actual output is:

Catched Error!
NameError: undefined local variable or method `bug_type=' for #<Bug:0x37867b45>
  method_missing at org/jruby/RubyBasicObject.java:1670
  method_missing at app/models/bug.rb:5
    set_bug_type at app/models/bug.rb:12
          (root) at app/models/bug.rb:17

This is happening using both JRuby 1.7.3 and 1.7.4.
The platform is a mac running MacOS X 10.8.4.

@BanzaiMan

This comment has been minimized.

Copy link
Member

BanzaiMan commented Jul 10, 2013

This looks like a duplicate of #540. Please close this if you agree.

@andrenpaes

This comment has been minimized.

Copy link
Author

andrenpaes commented Jul 10, 2013

Seems like different issues to me.

@headius

This comment has been minimized.

Copy link
Member

headius commented Jul 11, 2013

The relationship between NoMethodError and NameError is a little weird. In general I'd recommend sticking to NameError for these things, since depending on how something's parsed it might be one or the other.

That said, this appears to be specific to attribute assignment (and possible access), since we do the right thing for normal calls:

system ~/projects/jruby $ jruby -e "self.foo = 1"
NameError: undefined local variable or method `foo=' for main:Object
  (root) at -e:1

system ~/projects/jruby $ jruby -e "self.foo(1)"
NoMethodError: undefined method `foo' for main:Object
  (root) at -e:1

Will investigate.

@headius headius closed this in 5e97e4e Jul 11, 2013

@headius

This comment has been minimized.

Copy link
Member

headius commented Jul 11, 2013

Fixed! We appear to match MRI for a full range of call types now:

system ~/projects/jruby $ jruby -X-C -e 'def foo=(a); end; a = self; a.foo = 1'
NoMethodError: private method `foo=' called for main:Object
  (root) at -e:1

system ~/projects/jruby $ jruby -X-C -e 'def foo=(a); end; a = self; a.foo = 1'
NoMethodError: private method `foo=' called for main:Object
  (root) at -e:1

system ~/projects/jruby $ jruby -X-C -e 'def foo=(a); end; self.foo = 1'

system ~/projects/jruby $ jruby -X+C -e 'def foo=(a); end; a = self; a.foo = 1'
NoMethodError: private method `foo=' called for main:Object
  (root) at -e:1

system ~/projects/jruby $ jruby -X+C -e 'def foo=(a); end; self.foo = 1'

system ~/projects/jruby $ ruby2.0.0 -e 'def foo=(a); end; a = self; a.foo = 1'
-e:1:in `<main>': private method `foo=' called for main:Object (NoMethodError)

system ~/projects/jruby $ ruby2.0.0 -e 'def foo=(a); end; self.foo = 1'

system ~/projects/jruby $ jruby -X-C -e 'self.foo = 1'
NoMethodError: undefined method `foo=' for main:Object
  (root) at -e:1

system ~/projects/jruby $ jruby -X-C -e 'self.foo(1)'
NoMethodError: undefined method `foo' for main:Object
  (root) at -e:1

system ~/projects/jruby $ jruby -X-C -e 'foo(1)'
NoMethodError: undefined method `foo' for main:Object
  (root) at -e:1

system ~/projects/jruby $ jruby -X-C -e 'foo'
NameError: undefined local variable or method `foo' for main:Object
  (root) at -e:1

system ~/projects/jruby $ jruby -X+C -e 'self.foo = 1'
NoMethodError: undefined method `foo=' for main:Object
  (root) at -e:1

system ~/projects/jruby $ jruby -X+C -e 'self.foo(1)'
NoMethodError: undefined method `foo' for main:Object
  (root) at -e:1

system ~/projects/jruby $ jruby -X+C -e 'foo(1)'
NoMethodError: undefined method `foo' for main:Object
  (root) at -e:1

system ~/projects/jruby $ jruby -X+C -e 'foo'
NameError: undefined local variable or method `foo' for main:Object
  (root) at -e:1

system ~/projects/jruby $ ruby2.0.0 -e 'self.foo = 1'
-e:1:in `<main>': undefined method `foo=' for main:Object (NoMethodError)

system ~/projects/jruby $ ruby2.0.0 -e 'self.foo(1)'
-e:1:in `<main>': undefined method `foo' for main:Object (NoMethodError)

system ~/projects/jruby $ ruby2.0.0 -e 'foo(1)'
-e:1:in `<main>': undefined method `foo' for main:Object (NoMethodError)

system ~/projects/jruby $ ruby2.0.0 -e 'foo'
-e:1:in `<main>': undefined local variable or method `foo' for main:Object (NameError)

Could you perhaps turn these into a RubySpec (https://github.com/rubyspec/rubyspec) or JRuby regression spec (under spec/regression in https://github.com/jruby/jruby)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.