Skip to content

Commit 67ac948

Browse files
committed
Add C API rb_proc_call_kw function
1 parent dbc7695 commit 67ac948

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

spec/ruby/optional/capi/ext/proc_spec.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ VALUE proc_spec_rb_proc_call(VALUE self, VALUE prc, VALUE args) {
7676
return rb_proc_call(prc, args);
7777
}
7878

79+
VALUE proc_spec_rb_proc_call_kw(VALUE self, VALUE prc, VALUE args) {
80+
return rb_proc_call_kw(prc, args, RB_PASS_KEYWORDS);
81+
}
82+
7983
VALUE proc_spec_rb_proc_call_with_block(VALUE self, VALUE prc, VALUE args, VALUE block) {
8084
return rb_proc_call_with_block(prc, RARRAY_LENINT(args), RARRAY_PTR(args), block);
8185
}
@@ -127,6 +131,7 @@ void Init_proc_spec(void) {
127131
rb_define_method(cls, "rb_proc_new_block_given_p", proc_spec_rb_proc_new_block_given_p, 0);
128132
rb_define_method(cls, "rb_proc_arity", proc_spec_rb_proc_arity, 1);
129133
rb_define_method(cls, "rb_proc_call", proc_spec_rb_proc_call, 2);
134+
rb_define_method(cls, "rb_proc_call_kw", proc_spec_rb_proc_call_kw, 2);
130135
rb_define_method(cls, "rb_proc_call_with_block", proc_spec_rb_proc_call_with_block, 3);
131136
rb_define_method(cls, "rb_Proc_new", proc_spec_rb_Proc_new, 1);
132137
rb_define_method(cls, "rb_obj_is_proc", proc_spec_rb_obj_is_proc, 1);

spec/ruby/optional/capi/proc_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,25 @@
8282
end
8383
end
8484

85+
describe "rb_proc_call_kw" do
86+
it "passes keyword arguments to the proc" do
87+
prc = proc { |*args, **kw| [args, kw] }
88+
89+
@p.rb_proc_call_kw(prc, [{}]).should == [[], {}]
90+
@p.rb_proc_call_kw(prc, [{a: 1}]).should == [[], {a: 1}]
91+
@p.rb_proc_call_kw(prc, [{b: 2}, {a: 1}]).should == [[{b: 2}], {a: 1}]
92+
@p.rb_proc_call_kw(prc, [{b: 2}, {}]).should == [[{b: 2}], {}]
93+
end
94+
95+
it "raises TypeError if the last argument is not a Hash" do
96+
prc = proc { |*args, **kwargs| [args, kw] }
97+
98+
-> {
99+
@p.rb_proc_call_kw(prc, [42])
100+
}.should raise_error(TypeError, 'no implicit conversion of Integer into Hash')
101+
end
102+
end
103+
85104
describe "rb_proc_call_with_block" do
86105
it "calls the Proc and passes arguments and a block" do
87106
prc = Proc.new { |a, b, &block| block.call(a * b) }

src/main/c/cext/proc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ VALUE rb_proc_call(VALUE self, VALUE args) {
1919
return RUBY_CEXT_INVOKE("rb_proc_call", self, args);
2020
}
2121

22+
VALUE rb_proc_call_kw(VALUE recv, VALUE args, int kw_splat) {
23+
return rb_funcallv_kw(recv, rb_intern("call"), RARRAY_LENINT(args), RARRAY_PTR(args), kw_splat);
24+
}
25+
2226
VALUE rb_proc_call_with_block(VALUE recv, int argc, const VALUE *argv, VALUE proc) {
2327
return rb_funcall_with_block(recv, rb_intern("call"), argc, argv, proc);
2428
}

0 commit comments

Comments
 (0)