diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-05-27 23:22:28 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-10-12 16:20:57 +0900 |
| commit | dcd3e5907ca830f118bf7b55bbf1b1210a67385d (patch) | |
| tree | 713f95d62afc62d30a80860d6c1252dc19a8ceca | |
| parent | 80c15ddd1544f7cfe342701368cade2b5cec0193 (diff) | |
| download | mruby-dcd3e5907ca830f118bf7b55bbf1b1210a67385d.tar.gz mruby-dcd3e5907ca830f118bf7b55bbf1b1210a67385d.zip | |
Define a new function `mrb_funcall_id()`.
`mrb_funcall_id()` takes `mrb_sym` instead of `char*` for a method name.
You can use `MRB_SYM()`/`MRB_QSYM()` to specify the method to call.
| -rw-r--r-- | include/mruby.h | 41 | ||||
| -rw-r--r-- | src/vm.c | 19 |
2 files changed, 55 insertions, 5 deletions
diff --git a/include/mruby.h b/include/mruby.h index 148addf36..bbd6789c9 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -1031,6 +1031,36 @@ MRB_API mrb_value mrb_get_arg1(mrb_state *mrb); */ MRB_API mrb_value mrb_funcall(mrb_state *mrb, mrb_value val, const char *name, mrb_int argc, ...); /** + * Call existing ruby functions. + * + * Example: + * + * #include <stdio.h> + * #include <mruby.h> + * #include "mruby/compile.h" + * + * int + * main() + * { + * mrb_state *mrb = mrb_open(); + * + * if (!mrb) { } + * FILE *fp = fopen("test.rb","r"); + * mrb_value obj = mrb_load_file(mrb,fp); + * mrb_funcall_id(mrb, obj, MRB_SYM(method_name), 1, mrb_fixnum_value(i)); + * fclose(fp); + * mrb_close(mrb); + * } + * + * @param mrb The current mruby state. + * @param val A reference to an mruby value. + * @param name The symbol representing the method. + * @param argc The number of arguments the method has. + * @param ... Variadic values(not type safe!). + * @return [mrb_value] mruby function value. + */ +MRB_API mrb_value mrb_funcall_id(mrb_state *mrb, mrb_value val, mrb_sym mid, mrb_int argc, ...); +/** * Call existing ruby functions. This is basically the type safe version of mrb_funcall. * * #include <stdio.h> @@ -1039,15 +1069,14 @@ MRB_API mrb_value mrb_funcall(mrb_state *mrb, mrb_value val, const char *name, m * int * main() * { - * mrb_int i = 99; * mrb_state *mrb = mrb_open(); + * mrb_value obj = mrb_fixnum_value(1); * * if (!mrb) { } - * mrb_sym m_sym = mrb_intern_lit(mrb, "method_name"); // Symbol for method. * * FILE *fp = fopen("test.rb","r"); * mrb_value obj = mrb_load_file(mrb,fp); - * mrb_funcall_argv(mrb, obj, m_sym, 1, &obj); // Calling ruby function from test.rb. + * mrb_funcall_argv(mrb, obj, MRB_SYM(method_name), 1, &obj); // Calling ruby function from test.rb. * fclose(fp); * mrb_close(mrb); * } @@ -1065,7 +1094,7 @@ MRB_API mrb_value mrb_funcall_argv(mrb_state *mrb, mrb_value val, mrb_sym name, */ MRB_API mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value val, mrb_sym name, mrb_int argc, const mrb_value *argv, mrb_value block); /** - * Create a symbol + * Create a symbol from C string. But usually it's better to use MRB_SYM(sym) and MRB_QSYM(qsym). * * Example: * @@ -1073,7 +1102,9 @@ MRB_API mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value val, mrb_sym * :pizza # => :pizza * * // C style: - * mrb_sym m_sym = mrb_intern_lit(mrb, "pizza"); // => :pizza + * mrb_sym sym1 = mrb_intern_lit(mrb, "pizza"); // => :pizza + * mrb_sym sym2 = MRB_SYM(pizza); // => :pizza + * mrb_sym sym3 = MRB_SYM(pizza_p); // => :pizza? * * @param mrb The current mruby state. * @param str The string to be symbolized @@ -401,6 +401,25 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, mrb_int argc, ...) return mrb_funcall_argv(mrb, self, mid, argc, argv); } +MRB_API mrb_value +mrb_funcall_id(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, ...) +{ + mrb_value argv[MRB_FUNCALL_ARGC_MAX]; + va_list ap; + mrb_int i; + + if (argc > MRB_FUNCALL_ARGC_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=" MRB_STRINGIZE(MRB_FUNCALL_ARGC_MAX) ")"); + } + + va_start(ap, argc); + for (i = 0; i < argc; i++) { + argv[i] = va_arg(ap, mrb_value); + } + va_end(ap); + return mrb_funcall_argv(mrb, self, mid, argc, argv); +} + static int ci_nregs(mrb_callinfo *ci) { |
