Skip to content

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

Open
amunda opened this Issue Jul 18, 2014 · 9 comments

4 participants

@amunda
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
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
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
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 headius added the JRuby 1.7.x label Jan 7, 2015
@headius
JRuby Team member
headius commented Jan 7, 2015

@k77ch7 Looking...

@headius
JRuby Team 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
JRuby Team 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
JRuby Team 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
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
k77ch7 commented Jan 8, 2015

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.