summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro Matsumoto <[email protected]>2012-06-20 15:26:10 +0900
committerYukihiro Matsumoto <[email protected]>2012-06-20 15:26:10 +0900
commite9231bca7a5fafa67e0a15aa657e727e46a1363a (patch)
tree0da18886d14b2f7ca655c68a87b83a05c19fb1d5
parent88db589e7f965e5b16b82eca76f2e1febd82d124 (diff)
downloadmruby-e9231bca7a5fafa67e0a15aa657e727e46a1363a.tar.gz
mruby-e9231bca7a5fafa67e0a15aa657e727e46a1363a.zip
allow lambda duplication
-rw-r--r--src/proc.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/proc.c b/src/proc.c
index 21c462493..c64bb88ac 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -56,20 +56,40 @@ mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func)
return p;
}
+static inline void
+proc_copy(struct RProc *a, struct RProc *b)
+{
+ a->body = b->body;
+ a->target_class = b->target_class;
+ a->env = b->env;
+}
+
static mrb_value
mrb_proc_initialize(mrb_state *mrb, mrb_value self)
{
mrb_value blk;
mrb_get_args(mrb, "&", &blk);
- if (!mrb_nil_p(blk)) {
- *mrb_proc_ptr(self) = *mrb_proc_ptr(blk);
- }
- else {
+ if (mrb_nil_p(blk)) {
/* Calling Proc.new without a block is not implemented yet */
mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
}
+ else {
+ proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(blk));
+ }
+ return self;
+}
+
+static mrb_value
+mrb_proc_init_copy(mrb_state *mrb, mrb_value self)
+{
+ mrb_value proc;
+ mrb_get_args(mrb, "o", &proc);
+ if (mrb_type(proc) != MRB_TT_PROC) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc");
+ }
+ proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(proc));
return self;
}
@@ -108,8 +128,10 @@ mrb_init_proc(mrb_state *mrb)
call_irep->ilen = 1;
mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class);
+ MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC);
mrb_define_method(mrb, mrb->proc_class, "initialize", mrb_proc_initialize, ARGS_NONE());
+ mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, ARGS_REQ(1));
m = mrb_proc_new(mrb, call_irep);
mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "call"), m);