From 59c3b1c9c843fcd2d30393791fe224e5789d1677 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Mon, 7 Oct 2019 13:45:40 -0700 Subject: Add section to extension.rdoc for backwards compatibility macros [ci skip] These macros should make it easier to C extensions to switch to the Ruby 2.7 C-API *_kw functions, but still have the code work correctly on older Ruby versions. --- doc/extension.rdoc | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'doc') diff --git a/doc/extension.rdoc b/doc/extension.rdoc index 7807f98d6f..ea0a3d15f7 100644 --- a/doc/extension.rdoc +++ b/doc/extension.rdoc @@ -1920,6 +1920,48 @@ RB_EVENT_HOOKS_HAVE_CALLBACK_DATA :: Means that rb_add_event_hook() takes the third argument `data', to be passed to the given event hook function. +=== Defining backward compatible macros for keyword argument functions + +Most ruby C extensions are designed to support multiple Ruby versions. +In order to correctly support Ruby 2.7+ in regards to keyword +argument separation, C extensions need to use *_kw +functions. However, these functions do not exist in Ruby 2.6 and +below, so in those cases macros should be defined to allow you to use +the same code on multiple Ruby versions. Here are example macros +you can use in extensions that support Ruby 2.6 (or below) when using +the *_kw functions introduced in Ruby 2.7. + + #ifndef RB_PASS_KEYWORDS + /* Only define macros on Ruby <2.7 */ + #define rb_funcallv_kw(o, m, c, v, kw) rb_funcallv(o, m, c, v) + #define rb_funcallv_public_kw(o, m, c, v, kw) rb_funcallv_public(o, m, c, v) + #define rb_funcall_passing_block_kw(o, m, c, v, kw) rb_funcall_passing_block(o, m, c, v) + #define rb_funcall_with_block_kw(o, m, c, v, b, kw) rb_funcall_with_block(o, m, c, v, b) + #define rb_scan_args_kw(kw, c, v, s, ...) rb_scan_args(c, v, s, __VA_ARGS__) + #define rb_call_super_kw(c, v, kw) rb_call_super(c, v) + #define rb_yield_values_kw(c, v, kw) rb_yield_values2(c, v) + #define rb_yield_splat_kw(a, kw) rb_yield_splat(a) + #define rb_block_call_kw(o, m, c, v, f, p, kw) rb_block_call(o, m, c, v, f, p) + #define rb_fiber_resume_kw(o, c, v, kw) rb_fiber_resume(o, c, v) + #define rb_fiber_yield_kw(c, v, kw) rb_fiber_yield(c, v) + #define rb_enumeratorize_with_size_kw(o, m, c, v, f, kw) rb_enumeratorize_with_size(o, m, c, v, f) + #define SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) \ + rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), \ + (argc), (argv), (size_fn)) + #define RETURN_SIZED_ENUMERATOR_KW(obj, argc, argv, size_fn, kw_splat) do { \ + if (!rb_block_given_p()) \ + return SIZED_ENUMERATOR(obj, argc, argv, size_fn); \ + } while (0) + #define RETURN_ENUMERATOR_KW(obj, argc, argv, kw_splat) RETURN_SIZED_ENUMERATOR(obj, argc, argv, 0) + #define rb_check_funcall_kw(o, m, c, v, kw) rb_check_funcall(o, m, c, v) + #define rb_obj_call_init_kw(o, c, v, kw) rb_obj_call_init(o, c, v) + #define rb_class_new_instance_kw(c, v, k, kw) rb_class_new_instance(c, v, k) + #define rb_proc_call_kw(p, a, kw) rb_proc_call(p, a) + #define rb_proc_call_with_block_kw(p, c, v, b, kw) rb_proc_call_with_block(p, c, v, b) + #define rb_method_call_kw(c, v, m, kw) rb_method_call(c, v, m) + #define rb_method_call_with_block_kw(c, v, m, b, kw) rb_method_call_with_block(c, v, m, b) + #endif + == Appendix C. Functions available for use in extconf.rb See documentation for {mkmf}[rdoc-ref:MakeMakefile]. -- cgit v1.2.3