diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-12-20 20:18:25 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-12-23 10:01:30 +0900 |
| commit | 8d7e95282c64f482a28e7bc579857e781d03c74b (patch) | |
| tree | 758f1ffe54df84f99aa21f2dd8ee47969b41822f /mrbgems/mruby-class-ext/src/class.c | |
| parent | 7fbbd7ab9fdeb9eafe6a37fa7f16b60e41e21ad4 (diff) | |
| download | mruby-8d7e95282c64f482a28e7bc579857e781d03c74b.tar.gz mruby-8d7e95282c64f482a28e7bc579857e781d03c74b.zip | |
Add `#module_exec` and `#class_exec` in `mruby-class-ext` gem.
Diffstat (limited to 'mrbgems/mruby-class-ext/src/class.c')
| -rw-r--r-- | mrbgems/mruby-class-ext/src/class.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/mrbgems/mruby-class-ext/src/class.c b/mrbgems/mruby-class-ext/src/class.c index 5506c4829..705db9949 100644 --- a/mrbgems/mruby-class-ext/src/class.c +++ b/mrbgems/mruby-class-ext/src/class.c @@ -15,6 +15,42 @@ mrb_mod_singleton_class_p(mrb_state *mrb, mrb_value self) return mrb_bool_value(mrb_type(self) == MRB_TT_SCLASS); } +/* + * call-seq: + * module_exec(arg...) {|var...| block } -> obj + * class_exec(arg...) {|var...| block } -> obj + * + * Evaluates the given block in the context of the + * class/module. The method defined in the block will belong + * to the receiver. Any arguments passed to the method will be + * passed to the block. This can be used if the block needs to + * access instance variables. + * + * class Thing + * end + * Thing.class_exec{ + * def hello() "Hello there!" end + * } + * puts Thing.new.hello() + */ + +static mrb_value +mrb_mod_module_exec(mrb_state *mrb, mrb_value self) +{ + const mrb_value *argv; + mrb_int argc; + mrb_value blk; + + mrb_get_args(mrb, "*&", &argv, &argc, &blk); + + if (mrb_nil_p(blk)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); + } + + mrb->c->ci->target_class = mrb_class_ptr(self); + return mrb_yield_cont(mrb, blk, self, argc, argv); +} + void mrb_mruby_class_ext_gem_init(mrb_state *mrb) { @@ -22,6 +58,8 @@ mrb_mruby_class_ext_gem_init(mrb_state *mrb) mrb_define_method(mrb, mod, "name", mrb_mod_name, MRB_ARGS_NONE()); mrb_define_method(mrb, mod, "singleton_class?", mrb_mod_singleton_class_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, mod, "module_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); + mrb_define_method(mrb, mod, "class_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); } void |
