summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--proc.c21
-rw-r--r--test/ruby/test_method.rb16
2 files changed, 29 insertions, 8 deletions
diff --git a/proc.c b/proc.c
index 746c5e8bce..20efadc4ef 100644
--- a/proc.c
+++ b/proc.c
@@ -1387,6 +1387,15 @@ mnew_missing(VALUE klass, VALUE obj, ID id, VALUE mclass)
}
static VALUE
+mnew_missing_by_name(VALUE klass, VALUE obj, VALUE *name, int scope, VALUE mclass)
+{
+ VALUE vid = rb_str_intern(*name);
+ *name = vid;
+ if (!respond_to_missing_p(klass, obj, vid, scope)) return Qfalse;
+ return mnew_missing(klass, obj, SYM2ID(vid), mclass);
+}
+
+static VALUE
mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass,
VALUE obj, ID id, VALUE mclass, int scope, int error)
{
@@ -1690,10 +1699,8 @@ obj_method(VALUE obj, VALUE vid, int scope)
const VALUE mclass = rb_cMethod;
if (!id) {
- if (respond_to_missing_p(klass, obj, vid, scope)) {
- id = rb_intern_str(vid);
- return mnew_missing(klass, obj, id, mclass);
- }
+ VALUE m = mnew_missing_by_name(klass, obj, &vid, scope, mclass);
+ if (m) return m;
rb_method_name_error(klass, vid);
}
return mnew(klass, obj, id, mclass, scope);
@@ -1795,10 +1802,8 @@ rb_obj_singleton_method(VALUE obj, VALUE vid)
obj, vid);
}
if (!id) {
- if (respond_to_missing_p(klass, obj, vid, FALSE)) {
- id = rb_intern_str(vid);
- return mnew_missing(klass, obj, id, rb_cMethod);
- }
+ VALUE m = mnew_missing_by_name(klass, obj, &vid, FALSE, rb_cMethod);
+ if (m) return m;
goto undef;
}
me = rb_method_entry_at(klass, id);
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index 6647ff86f4..f313279f62 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -494,6 +494,22 @@ class TestMethod < Test::Unit::TestCase
assert_include mmethods, :meth, 'normal methods are public by default'
end
+ def test_respond_to_missing_argument
+ obj = Struct.new(:mid).new
+ def obj.respond_to_missing?(id, *)
+ self.mid = id
+ true
+ end
+ assert_kind_of(Method, obj.method("bug15640"))
+ assert_kind_of(Symbol, obj.mid)
+ assert_equal("bug15640", obj.mid.to_s)
+
+ arg = Struct.new(:to_str).new("bug15640_2")
+ assert_kind_of(Method, obj.method(arg))
+ assert_kind_of(Symbol, obj.mid)
+ assert_equal("bug15640_2", obj.mid.to_s)
+ end
+
define_method(:pm0) {||}
define_method(:pm1) {|a|}
define_method(:pm2) {|a, b|}