summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal.h1
-rw-r--r--string.c3
-rw-r--r--test/ruby/test_symbol.rb7
-rw-r--r--vm_args.c4
4 files changed, 14 insertions, 1 deletions
diff --git a/internal.h b/internal.h
index 10775a7e68..00fbabbf93 100644
--- a/internal.h
+++ b/internal.h
@@ -1110,6 +1110,7 @@ VALUE rb_external_str_with_enc(VALUE str, rb_encoding *eenc);
#define is_broken_string(str) (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN)
size_t rb_str_memsize(VALUE);
VALUE rb_sym_proc_call(VALUE args, VALUE sym, int argc, const VALUE *argv, VALUE passed_proc);
+VALUE rb_sym_to_proc(VALUE sym);
/* struct.c */
VALUE rb_struct_init_copy(VALUE copy, VALUE s);
diff --git a/string.c b/string.c
index 907b47c1a4..50e5c906eb 100644
--- a/string.c
+++ b/string.c
@@ -8946,6 +8946,7 @@ rb_sym_proc_call(VALUE args, VALUE sym, int argc, const VALUE *argv, VALUE passe
return rb_funcall_with_block(obj, (ID)sym, argc - 1, argv + 1, passed_proc);
}
+#define sym_to_proc rb_sym_to_proc
/*
* call-seq:
* sym.to_proc
@@ -8955,7 +8956,7 @@ rb_sym_proc_call(VALUE args, VALUE sym, int argc, const VALUE *argv, VALUE passe
* (1..3).collect(&:to_s) #=> ["1", "2", "3"]
*/
-static VALUE
+VALUE
sym_to_proc(VALUE sym)
{
static VALUE sym_proc_cache = Qfalse;
diff --git a/test/ruby/test_symbol.rb b/test/ruby/test_symbol.rb
index 3d1f45a927..1329ea22ab 100644
--- a/test/ruby/test_symbol.rb
+++ b/test/ruby/test_symbol.rb
@@ -140,6 +140,13 @@ class TestSymbol < Test::Unit::TestCase
end;
end
+ def test_to_proc_arg
+ assert_separately([], <<-"end;", timeout: 5.0)
+ def (obj = Object.new).proc(&b) b; end
+ assert_same(:itself.to_proc, obj.proc(&:itself))
+ end;
+ end
+
def test_call
o = Object.new
def o.foo(x, y); x + y; end
diff --git a/vm_args.c b/vm_args.c
index 18911b4a5d..b031c0dc64 100644
--- a/vm_args.c
+++ b/vm_args.c
@@ -478,6 +478,10 @@ args_setup_block_parameter(rb_thread_t *th, struct rb_calling_info *calling, VAL
GetProcPtr(blockval, proc);
calling->blockptr = &proc->block;
}
+ else if (RUBY_VM_IFUNC_P(blockptr->proc)) {
+ const ID mid = (ID)((struct vm_ifunc *)blockptr->proc)->data;
+ blockval = rb_sym_to_proc(ID2SYM(mid));
+ }
else {
blockval = blockptr->proc;
}