-
-
Notifications
You must be signed in to change notification settings - Fork 924
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
Inconsistency between MRI and JRuby when private methods are called and method_missing is present #540
Comments
Still present in 1.7.20 and HEAD:
|
Obviously it is very unfortunate that Rails tests depend on the error message, but in this case we're not just worded differently...we're missing information. I'll have a look. |
Hmm...this is a very unusual case. In MRI, it seems that the call through user-defined method_missing keeps some state around indicating the original reason for the method_missing call. This data is not visible to users except when that method_missing calls super. In JRuby, once method_missing has dispatched, we do not track the original cause; either an error will be thrown, or we'll go back into userland for the user to handle it. It gets even weirder (to me, at least). The error message is preserved:
def method_missing name
->{super}
end
Given that there can be many changes to the call stack and the cause is still preserved, it seems likely that MRI has special call logic for method_missing that carries this information along. |
Ah-ha! When I looked into MRI's code for this, I saw that they track the cause in a So I thought I'd trigger another method_missing before calling super. The following code does not raise the correct error at all: class A
def method_missing(name)
return if name == :bar
bar rescue nil
super
end
def foo; end
private :foo
end
A.new.foo
__END__
[] ~/projects/ruby $ rvm ruby-2.2 do ruby ../jruby/super_thing.rb
../jruby/super_thing.rb:11:in `method_missing': undefined local variable or method `foo' for #<A:0x007f8b648da990> (NameError)
from ../jruby/super_thing.rb:18:in `<main>' The output here seems to confirm that this value is indeed thread-local, and once wiped out by another value it cannot be recovered. I almost feel like the method_missing Nevertheless...it's a much smaller change to have method_missing dispatch briefly update a thread-local variable to indicate the cause. This should be fixable. |
This also simplifies the pre-built "visibility m_m's" and eliminates a few inner classes. Fixes #540.
Zing. Hope I didn't break anything. I think we need some specs for this. |
this code will generate an exception with different messages under MRI and JRuby.
MRI:
JRuby:
Notice that JRuby's exception doesn't mention that the method we're trying to access is private. This cause three specs to fail in rails since unfortunately they rely on the wording of the exception.
The text was updated successfully, but these errors were encountered: