fn module_eval(vm: &mut VM, self_value: Value, args: &Args2) -> VMResult {
    let self_val = self_value.into_module();
    match &args.block {
        None => {
            args.check_args_min(1)?;
            let mut arg0 = vm[0];
            let program = arg0.expect_string("1st arg")?;
            let method = vm.parse_program_eval("(eval)", program.to_string())?;
            // The scopes of constants and class variables are same as module definition of `self_val`.
            let mut iseq = vm.caller_method_iseq();
            iseq.class_defined.push(self_val);
            let res =
                vm.eval_block_with_methodid(method, self_val, vm.caller_cfp().ep(), &Args::new0());
            iseq.class_defined.pop().unwrap();
            res
        }
        Some(block) => {
            args.check_args_min(0)?;
            // The scopes of constants and class variables are outer of the block.
            let res = vm.eval_block_self(block, self_val, &Args::new1(self_value));
            res
        }
    }
}
module_eval(expr, fname = "(eval)", lineno = 1) -> object
module_eval {|mod| ... } -> object
class_eval(expr, fname = "(eval)", lineno = 1) -> object
class_eval {|mod| ... } -> object
https://docs.ruby-lang.org/ja/latest/method/Module/i/class_eval.html
ruruby/src/builtin/module.rs