diff --git a/CHANGELOG.md b/CHANGELOG.md index 267549ee5a9b..5f91ca99dbb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Compatibility: * Remove deprecated `Pathname#{taint,untaint}` methods (#3681, @andrykonchin). * Add `rb_category_warn` function (#3710, @andrykonchin). * Add `rb_gc_mark_locations()` (#3704, @andrykonchin). +* Implement `rb_str_format()` (#3716, @andrykonchin). Performance: diff --git a/lib/truffle/truffle/cext.rb b/lib/truffle/truffle/cext.rb index 4c7554fd3722..e337ceb3914e 100644 --- a/lib/truffle/truffle/cext.rb +++ b/lib/truffle/truffle/cext.rb @@ -1416,6 +1416,10 @@ def rb_f_sprintf(args) sprintf(*args) end + def rb_str_format(args, format) + sprintf(format, *args) + end + def rb_io_printf(out, args) out.printf(*args) end diff --git a/spec/ruby/optional/capi/ext/kernel_spec.c b/spec/ruby/optional/capi/ext/kernel_spec.c index 56448010d8aa..f2ce94bd8914 100644 --- a/spec/ruby/optional/capi/ext/kernel_spec.c +++ b/spec/ruby/optional/capi/ext/kernel_spec.c @@ -332,6 +332,10 @@ static VALUE kernel_spec_rb_f_sprintf(VALUE self, VALUE ary) { return rb_f_sprintf((int)RARRAY_LEN(ary), RARRAY_PTR(ary)); } +static VALUE kernel_spec_rb_str_format(VALUE self, VALUE count, VALUE ary, VALUE format) { + return rb_str_format(FIX2INT(count), RARRAY_PTR(ary), format); +} + static VALUE kernel_spec_rb_make_backtrace(VALUE self) { return rb_make_backtrace(); } @@ -421,6 +425,7 @@ void Init_kernel_spec(void) { rb_define_method(cls, "rb_exec_recursive", kernel_spec_rb_exec_recursive, 1); rb_define_method(cls, "rb_set_end_proc", kernel_spec_rb_set_end_proc, 1); rb_define_method(cls, "rb_f_sprintf", kernel_spec_rb_f_sprintf, 1); + rb_define_method(cls, "rb_str_format", kernel_spec_rb_str_format, 3); rb_define_method(cls, "rb_make_backtrace", kernel_spec_rb_make_backtrace, 0); rb_define_method(cls, "rb_funcallv", kernel_spec_rb_funcallv, 3); #ifdef RUBY_VERSION_IS_3_0 diff --git a/spec/ruby/optional/capi/kernel_spec.rb b/spec/ruby/optional/capi/kernel_spec.rb index 50e8b2f3fdc7..43eea07182c9 100644 --- a/spec/ruby/optional/capi/kernel_spec.rb +++ b/spec/ruby/optional/capi/kernel_spec.rb @@ -892,4 +892,10 @@ def obj.method_missing(name, *args) @s.rb_check_funcall(object, :protected_method, []).should == :protected end end + + describe "rb_str_format" do + it "returns a string according to format and arguments" do + @s.rb_str_format(3, [10, 2.5, "test"], "%d %f %s").should == "10 2.500000 test" + end + end end diff --git a/src/main/c/cext/printf.c b/src/main/c/cext/printf.c index ed85ce92dd95..06fccad812aa 100644 --- a/src/main/c/cext/printf.c +++ b/src/main/c/cext/printf.c @@ -183,3 +183,7 @@ VALUE rb_str_vcatf(VALUE str, const char *fmt, va_list args) { rb_str_concat(str, result); return str; } + +VALUE rb_str_format(int argc, const VALUE *argv, VALUE fmt) { + return RUBY_CEXT_INVOKE("rb_str_format", rb_ary_new4(argc, argv), fmt); +}