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:
dearblue
2026-05-08 11:51:25 +09:00
committed by Yukihiro "Matz" Matsumoto
parent 817ec1bd90
commit cf20687ee7
+24 -35
View File
@@ -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);
}
/*