Skip to content

Commit 8c9ee5c

Browse files
committed
Implement rb_yield_values2
1 parent ff4b7df commit 8c9ee5c

File tree

4 files changed

+31
-0
lines changed

4 files changed

+31
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Compatibility:
3030
* Skip upgraded default gems while loading RubyGems (#2075).
3131
* Verify that gem paths are correct before loading RubyGems (#2075).
3232
* Implement `rb_ivar_count`.
33+
* Implemented `rb_yield_values2`.
3334

3435
Performance:
3536

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,15 @@ static VALUE kernel_spec_rb_yield_values(VALUE self, VALUE obj1, VALUE obj2) {
270270
return rb_yield_values(2, obj1, obj2);
271271
}
272272

273+
static VALUE kernel_spec_rb_yield_values2(VALUE self, VALUE ary) {
274+
long len = RARRAY_LEN(ary);
275+
VALUE *args = (VALUE*)alloca(sizeof(VALUE) * len);
276+
for (int i = 0; i < len; i++) {
277+
args[i] = rb_ary_entry(ary, i);
278+
}
279+
return rb_yield_values2((int)len, args);
280+
}
281+
273282
static VALUE do_rec(VALUE obj, VALUE arg, int is_rec) {
274283
if(is_rec) {
275284
return obj;
@@ -351,6 +360,7 @@ void Init_kernel_spec(void) {
351360
rb_define_method(cls, "rb_yield_indirected", kernel_spec_rb_yield_indirected, 1);
352361
rb_define_method(cls, "rb_yield_define_each", kernel_spec_rb_yield_define_each, 1);
353362
rb_define_method(cls, "rb_yield_values", kernel_spec_rb_yield_values, 2);
363+
rb_define_method(cls, "rb_yield_values2", kernel_spec_rb_yield_values2, 1);
354364
rb_define_method(cls, "rb_yield_splat", kernel_spec_rb_yield_splat, 1);
355365
rb_define_method(cls, "rb_exec_recursive", kernel_spec_rb_exec_recursive, 1);
356366
rb_define_method(cls, "rb_set_end_proc", kernel_spec_rb_set_end_proc, 1);

spec/ruby/optional/capi/kernel_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,18 @@
238238
end
239239
end
240240

241+
describe "rb_yield_values2" do
242+
it "yields passed arguments" do
243+
ret = nil
244+
@s.rb_yield_values2([1, 2]) { |x, y| ret = x + y }
245+
ret.should == 3
246+
end
247+
248+
it "returns the result from block evaluation" do
249+
@s.rb_yield_values2([1, 2]) { |x, y| x + y }.should == 3
250+
end
251+
end
252+
241253
describe "rb_yield_splat" do
242254
it "yields with passed array's contents" do
243255
ret = nil

src/main/c/cext/call.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ VALUE rb_yield_values(int n, ...) {
9393
return rb_yield_splat(values);
9494
}
9595

96+
VALUE rb_yield_values2(int n, const VALUE *argv) {
97+
VALUE values = rb_ary_new_capa(n);
98+
for (int i = 0; i < n; i++) {
99+
rb_ary_store(values, i, (VALUE) argv[i]);
100+
}
101+
return rb_yield_splat(values);
102+
}
103+
96104
void *rb_thread_call_with_gvl(gvl_call function, void *data1) {
97105
return polyglot_invoke(RUBY_CEXT, "rb_thread_call_with_gvl", function, data1);
98106
}

0 commit comments

Comments
 (0)