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

responds_to?(:method_missing) always return false in 1.7.13 #1829

Closed
amunda opened this issue Jul 18, 2014 · 12 comments
Closed

responds_to?(:method_missing) always return false in 1.7.13 #1829

amunda opened this issue Jul 18, 2014 · 12 comments

Comments

@amunda
Copy link

amunda commented Jul 18, 2014

We notice that since we upgrade to 1.7.13 responds_to?(:method_missing) always returns false.

Here is a sample class which gave the following results when run with JRuby 1.7.9, Ruby 1.9.3 and JRuby 1.7.13

class MethodMissingTest 
  def method_missing(method_name, *args)
  end

  def my_test_method
  end

  def output
    puts "Responds to method_missing #{respond_to?(:method_missing)}"
    puts "Responds to my_test_method #{respond_to?(:my_test_method)}"
  end
end

In MRI (Ruby 1.9.3) & JRuby (1.7.9)
Responds to method_missing true
Responds to my_test_method true

In JRuby (1.7.13)
Responds to method_missing false
Responds to my_test_method true

This is causing us to break our Rails application specially when we use method_missing in our controller to render some of the actions because Rails framework relies on this call.

@k77ch7
Copy link
Contributor

k77ch7 commented Dec 30, 2014

In JRuby (master branch)
Responds to method_missing true
Responds to my_test_method true

In JRuby (1_7 branch) & In JRuby (1.7.18)
esponds to method_missing false
Responds to my_test_method true

@k77ch7
Copy link
Contributor

k77ch7 commented Dec 31, 2014

In MRI (Ruby 2.0.0) & In MRI (Ruby 2.1.0)
Responds to method_missing true
Responds to my_test_method true

@k77ch7
Copy link
Contributor

k77ch7 commented Jan 4, 2015

I suppose the conditional expression in core/src/main/java/org/jruby/runtime/Helpers.java causes this issue. Regardless of the declaration of method_missing, the visibility of method_missing is always Visibility.PRIVATE.
This is a my patch to fix this issue on jruby-1_7 branch.

diff --git a/core/src/main/java/org/jruby/runtime/Helpers.java b/core/src/main/java/org/jruby/runtime/Helpers.java
index 5404190..daf3bb6 100644
--- a/core/src/main/java/org/jruby/runtime/Helpers.java
+++ b/core/src/main/java/org/jruby/runtime/Helpers.java
@@ -2039,7 +2039,7 @@ public class Helpers {
         DynamicMethod method;
         final Ruby runtime = containingClass.getRuntime();

-        if ("initialize".equals(name) || "initialize_copy".equals(name) || "method_missing".equals(name) || visibility == Visibility.MODULE_FUNCTION) {
+        if ("initialize".equals(name) || "initialize_copy".equals(name) || visibility == Visibility.MODULE_FUNCTION) {
             visibility = Visibility.PRIVATE;
         } else if (runtime.is2_0() && ("respond_to_missing?".equals(name) || "initialize_clone".equals(name) || "initialize_dup".equals(name))) {
             visibility = Visibility.PRIVATE;

@enebo @headius please review my patch. Thank you.

@headius
Copy link
Member

headius commented Jan 7, 2015

@k77ch7 Looking...

@headius
Copy link
Member

headius commented Jan 7, 2015

Weird...I can find no place in MRI where they special case either method_missing or respond_to_missing? to force them to always be private. In fact, I can't find any code in MRI 2.2 that does this for initialize forms either.

Testing across versions:

~/projects/ruby $ rvm ruby-2.2 do ruby -e "class Foo; def method_missing(*); end; def respond_to_missing?(*); end; def initialize; end; end; Foo.new.method_missing; Foo.new.respond_to_missing?; Foo.new.initialize"

~/projects/ruby $ rvm ruby-2.2 do ruby -e "class Foo; def method_missing(*); end; def respond_to_missing?(*); end; def initialize; end; end; Foo.new.method_missing; Foo.new.respond_to_missing?; Foo.new.initialize"

~/projects/ruby $ rvm ruby-2.1 do ruby -e "class Foo; def method_missing(*); end; def respond_to_missing?(*); end; def initialize; end; end; Foo.new.method_missing; Foo.new.respond_to_missing?; Foo.new.initialize"

~/projects/ruby $ rvm ruby-2.0 do ruby -e "class Foo; def method_missing(*); end; def respond_to_missing?(*); end; def initialize; end; end; Foo.new.method_missing; Foo.new.respond_to_missing?; Foo.new.initialize"

~/projects/ruby $ rvm ruby-1.9 do ruby -e "class Foo; def method_missing(*); end; def respond_to_missing?(*); end; def initialize; end; end; Foo.new.method_missing; Foo.new.respond_to_missing?; Foo.new.initialize"

~/projects/ruby $ rvm ruby-1.8 do ruby -e "class Foo; def method_missing(*); end; def respond_to_missing?(*); end; def initialize; end; end; Foo.new.method_missing; Foo.new.respond_to_missing?; Foo.new.initialize"

~/projects/ruby $

I have maintained this private logic for years, and now I can find no evidence that MRI ever did it. I must be going mad.

@headius
Copy link
Member

headius commented Jan 7, 2015

Here's a diff that removes the private-forcing logic. I do not have cycles this evening to make sure that MRI does not still have private-forcing logic somewhere.

diff --git a/core/src/main/java/org/jruby/runtime/Helpers.java b/core/src/main/java/org/jruby/runtime/Helpers.java
index 9d01515..4ed539c 100644
--- a/core/src/main/java/org/jruby/runtime/Helpers.java
+++ b/core/src/main/java/org/jruby/runtime/Helpers.java
@@ -2039,12 +2039,6 @@ public class Helpers {

         DynamicMethod method;
         final Ruby runtime = containingClass.getRuntime();
-
-        if ("initialize".equals(name) || "initialize_copy".equals(name) || "method_missing".equals(name) || visibility == Visibility.MODULE_FUNCTION) {
-            visibility = Visibility.PRIVATE;
-        } else if (runtime.is2_0() && ("respond_to_missing?".equals(name) || "initialize_clone".equals(name) || "initialize_dup".equals(name))) {
-            visibility = Visibility.PRIVATE;
-        }

         if (RubyInstanceConfig.LAZYHANDLES_COMPILE) {
             method = factory.getCompiledMethodLazily(

@headius
Copy link
Member

headius commented Jan 7, 2015

Weird... it looks like this logic was added or modified by @tduehr in 9c758b4.

@tduehr Did you see this logic in MRI?

@tduehr
Copy link
Contributor

tduehr commented Jan 7, 2015

I did that based on the pickaxe it looks like that chunk was in error. It starts as a private method but when re-defined, is public. it seems this change was in error.

@k77ch7
Copy link
Contributor

k77ch7 commented Jan 8, 2015

@headius @tduehr Thank you. I hope that @headius 's patch is applied to jruby-1_7 branch.

@kares
Copy link
Member

kares commented Jan 17, 2017

correct (respond_to_missing related) logic has been backported at some point. should be good with 1.7.26

@kares kares closed this as completed Jan 17, 2017
@kares
Copy link
Member

kares commented Jan 17, 2017

actually it fails on 1.7.26 (its doing fine on 9K e.g. 9.1.7.0 returning true, true) :

Responds to method_missing false
Responds to my_test_method true

@kares kares reopened this Jan 17, 2017
@kares kares added the core label Jan 17, 2017
@kares kares added this to the JRuby 1.7.27 milestone Jan 17, 2017
@headius
Copy link
Member

headius commented Mar 15, 2017

I'm not sure we're going to bother fixing this after so long, especially since it works properly on 9k. Please upgrade. If you are really stuck by this, open a new issue.

@headius headius closed this as completed Mar 15, 2017
@headius headius modified the milestones: Won't Fix, JRuby 1.7.27 Mar 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants