mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-eval: unify f_instance_eval and f_class_eval
Their bodies were nearly identical: same argument parsing, same proc creation, same target-class plumbing. The only differences are which method to delegate to in the block-given case (mrb_obj_instance_eval vs. mrb_mod_module_eval) and which class to use as the target (singleton vs. self-as-class). Extract the shared logic into object_eval(self, class_eval). The two top-level dispatchers become one-line wrappers. Closes #6579, picked from PR by dearblue. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
committed by
Yukihiro "Matz" Matsumoto
parent
817ec1bd90
commit
cf20687ee7
@@ -322,27 +322,32 @@ f_eval(mrb_state *mrb, mrb_value self)
|
||||
* k.instance_eval { the_secret } #=> "Ssssh! The secret is 99."
|
||||
* k.instance_eval("@secret = 5") #=> 5
|
||||
*/
|
||||
static mrb_value
|
||||
object_eval(mrb_state *mrb, mrb_value self, mrb_bool class_eval)
|
||||
{
|
||||
if (mrb_block_given_p(mrb)) {
|
||||
mrb_get_args(mrb, "");
|
||||
return class_eval ? mrb_mod_module_eval(mrb, self) : mrb_obj_instance_eval(mrb, self);
|
||||
}
|
||||
|
||||
const char *s;
|
||||
mrb_int len;
|
||||
const char *file = NULL;
|
||||
mrb_int line = 1;
|
||||
mrb_get_args(mrb, "s|zi", &s, &len, &file, &line);
|
||||
|
||||
struct RClass *c = class_eval ? mrb_class_ptr(self) : mrb_singleton_class_ptr(mrb, self);
|
||||
struct RProc *proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line);
|
||||
MRB_PROC_SET_TARGET_CLASS(proc, c);
|
||||
mrb_assert(!MRB_PROC_CFUNC_P(proc));
|
||||
mrb_vm_ci_target_class_set(mrb->c->ci, c);
|
||||
return eval_irep(mrb, self, proc);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
f_instance_eval(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
if (!mrb_block_given_p(mrb)) {
|
||||
const char *s;
|
||||
mrb_int len;
|
||||
const char *file = NULL;
|
||||
mrb_int line = 1;
|
||||
|
||||
mrb_get_args(mrb, "s|zi", &s, &len, &file, &line);
|
||||
struct RClass *c = mrb_singleton_class_ptr(mrb, self);
|
||||
struct RProc *proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line);
|
||||
MRB_PROC_SET_TARGET_CLASS(proc, c);
|
||||
mrb_assert(!MRB_PROC_CFUNC_P(proc));
|
||||
mrb_vm_ci_target_class_set(mrb->c->ci, c);
|
||||
return eval_irep(mrb, self, proc);
|
||||
}
|
||||
else {
|
||||
mrb_get_args(mrb, "");
|
||||
return mrb_obj_instance_eval(mrb, self);
|
||||
}
|
||||
return object_eval(mrb, self, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -369,23 +374,7 @@ f_instance_eval(mrb_state *mrb, mrb_value self)
|
||||
static mrb_value
|
||||
f_class_eval(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
if (!mrb_block_given_p(mrb)) {
|
||||
const char *s;
|
||||
mrb_int len;
|
||||
const char *file = NULL;
|
||||
mrb_int line = 1;
|
||||
|
||||
mrb_get_args(mrb, "s|zi", &s, &len, &file, &line);
|
||||
struct RProc *proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line);
|
||||
MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(self));
|
||||
mrb_assert(!MRB_PROC_CFUNC_P(proc));
|
||||
mrb_vm_ci_target_class_set(mrb->c->ci, mrb_class_ptr(self));
|
||||
return eval_irep(mrb, self, proc);
|
||||
}
|
||||
else {
|
||||
mrb_get_args(mrb, "");
|
||||
return mrb_mod_module_eval(mrb, self);
|
||||
}
|
||||
return object_eval(mrb, self, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user