aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2023-01-22 11:40:37 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2023-10-26 17:28:50 +0900
commit1507118f0b70fc8002b4b0f186b464c64965cd1e (patch)
treef6675bc00514e1a3793e506d581aaafe10e9d42e
parent7d159a87873d72027a8230d9cb63698d1f3c5cac (diff)
downloadruby-1507118f0b70fc8002b4b0f186b464c64965cd1e.tar.gz
[Feature #19362] Call `#initialize_dup` hook at `Proc#dup`
-rw-r--r--proc.c12
-rw-r--r--test/ruby/test_proc.rb9
2 files changed, 20 insertions, 1 deletions
diff --git a/proc.c b/proc.c
index 0f4735b589..81a5261413 100644
--- a/proc.c
+++ b/proc.c
@@ -152,6 +152,16 @@ proc_clone(VALUE self)
{
VALUE procval = rb_proc_dup(self);
CLONESETUP(procval, self);
+ rb_check_funcall(procval, idInitialize_clone, 1, &self);
+ return procval;
+}
+
+/* :nodoc: */
+static VALUE
+proc_dup(VALUE self)
+{
+ VALUE procval = rb_proc_dup(self);
+ rb_check_funcall(procval, idInitialize_dup, 1, &self);
return procval;
}
@@ -4258,7 +4268,7 @@ Init_Proc(void)
rb_define_method(rb_cProc, "to_proc", proc_to_proc, 0);
rb_define_method(rb_cProc, "arity", proc_arity, 0);
rb_define_method(rb_cProc, "clone", proc_clone, 0);
- rb_define_method(rb_cProc, "dup", rb_proc_dup, 0);
+ rb_define_method(rb_cProc, "dup", proc_dup, 0);
rb_define_method(rb_cProc, "hash", proc_hash, 0);
rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
rb_define_alias(rb_cProc, "inspect", "to_s");
diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb
index 4245a7b785..8d6ebf5dcb 100644
--- a/test/ruby/test_proc.rb
+++ b/test/ruby/test_proc.rb
@@ -388,6 +388,15 @@ class TestProc < Test::Unit::TestCase
def test_dup_subclass
c1 = Class.new(Proc)
assert_equal c1, c1.new{}.dup.class, '[Bug #17545]'
+ c1 = Class.new(Proc) {def initialize_dup(*) throw :initialize_dup; end}
+ assert_throw(:initialize_dup) {c1.new{}.dup}
+ end
+
+ def test_clone_subclass
+ c1 = Class.new(Proc)
+ assert_equal c1, c1.new{}.clone.class, '[Bug #17545]'
+ c1 = Class.new(Proc) {def initialize_clone(*) throw :initialize_clone; end}
+ assert_throw(:initialize_clone) {c1.new{}.clone}
end
def test_binding