diff options
Diffstat (limited to 'src/proc.c')
| -rw-r--r-- | src/proc.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/proc.c b/src/proc.c index c64bb88ac..98f753ac6 100644 --- a/src/proc.c +++ b/src/proc.c @@ -59,6 +59,7 @@ mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func) static inline void proc_copy(struct RProc *a, struct RProc *b) { + a->flags = b->flags; a->body = b->body; a->target_class = b->target_class; a->env = b->env; @@ -111,6 +112,35 @@ mrb_proc_iseq(mrb_state *mrb, struct RProc *p) return p->body.irep->iseq; } +/* 15.3.1.2.6 */ +/* 15.3.1.3.27 */ +/* + * call-seq: + * lambda { |...| block } -> a_proc + * + * Equivalent to <code>Proc.new</code>, except the resulting Proc objects + * check the number of parameters passed when called. + */ +static mrb_value +proc_lambda(mrb_state *mrb, mrb_value self) +{ + mrb_value blk; + struct RProc *p; + + mrb_get_args(mrb, "&", &blk); + if (mrb_nil_p(blk)) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); + } + p = mrb_proc_ptr(blk); + if (!MRB_PROC_STRICT_P(p)) { + struct RProc *p2 = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, p->c); + proc_copy(p2, p); + p2->flags |= MRB_PROC_STRICT; + return mrb_obj_value(p2); + } + return self; +} + void mrb_init_proc(mrb_state *mrb) { @@ -136,4 +166,7 @@ mrb_init_proc(mrb_state *mrb) m = mrb_proc_new(mrb, call_irep); mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "call"), m); mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "[]"), m); + + mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.2.6 */ + mrb_define_method(mrb, mrb->kernel_module, "lambda", proc_lambda, ARGS_NONE()); /* 15.3.1.3.27 */ } |
