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
Closed

NameError is thrown by method_missing when using self #872

andrenpaes opened this issue Jul 10, 2013 · 4 comments
Labels
Milestone

Comments

@andrenpaes
Copy link

@andrenpaes 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
Copy link
Member

@BanzaiMan BanzaiMan commented Jul 10, 2013

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

@andrenpaes
Copy link
Author

@andrenpaes andrenpaes commented Jul 10, 2013

Seems like different issues to me.

@headius
Copy link
Member

@headius 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
Copy link
Member

@headius 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
Labels
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants