mirb: show method context for errors from previous code

runtime errors now distinguish between:
- errors in current input: show relative line number
- errors from previously defined methods: show method context

examples:
1> a.foo
line 1: undefined method 'a' for Object (NoMethodError)

1> def foo
2*   bar
3* end
1> foo
(mirb):in foo: undefined method 'bar' for Object (NoMethodError)

this provides better context since method name is more useful
than line number for errors in previously defined code

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-12-03 20:25:41 +09:00
parent ac39b7d8ad
commit 9aa6f28eab
+26 -6
View File
@@ -131,7 +131,7 @@ p(mrb_state *mrb, mrb_value obj)
}
static void
p_error(mrb_state *mrb, struct RObject* exc)
p_error(mrb_state *mrb, struct RObject* exc, mrb_ccontext *cxt)
{
mrb_value val = mrb_exc_get_output(mrb, exc);
if (!mrb_string_p(val)) {
@@ -143,10 +143,30 @@ p_error(mrb_state *mrb, struct RObject* exc)
if (mrb_array_p(bt) && RARRAY_LEN(bt) > 0) {
mrb_value location = RARRAY_PTR(bt)[0];
if (mrb_string_p(location)) {
char* loc_msg = mrb_locale_from_utf8(RSTRING_PTR(location), (int)RSTRING_LEN(location));
fputs(loc_msg, stdout);
fputs(": ", stdout);
mrb_locale_free(loc_msg);
const char *loc_str = RSTRING_PTR(location);
/* parse location string: "(mirb):LINE" or "(mirb):LINE:in method" */
const char *colon = strchr(loc_str, ':');
if (colon && colon[1] >= '0' && colon[1] <= '9') {
/* check if there's a method name - this means error is from previous code */
const char *in_pos = strstr(colon + 1, ":in ");
if (in_pos) {
/* error inside a previously defined method */
char* loc_msg = mrb_locale_from_utf8(in_pos, (int)RSTRING_LEN(location) - (int)(in_pos - loc_str));
printf("(mirb)%s: ", loc_msg);
mrb_locale_free(loc_msg);
}
else {
/* no method name - could be current or previous top-level code */
int err_line = atoi(colon + 1);
if (err_line >= cxt->lineno) {
/* error in current input - show relative line number */
int relative_line = err_line - cxt->lineno + 1;
printf("line %d: ", relative_line);
}
/* else: error from top-level previous code, no location shown */
}
}
}
}
@@ -750,7 +770,7 @@ main(int argc, char **argv)
/* did an exception occur? */
if (mrb->exc) {
MRB_EXC_CHECK_EXIT(mrb, mrb->exc);
p_error(mrb, mrb->exc);
p_error(mrb, mrb->exc, cxt);
mrb->exc = 0;
}
else {