From 4b583cff97025394fab4a014a2a8606dfb557475 Mon Sep 17 00:00:00 2001 From: zverok Date: Sun, 27 Oct 2019 12:39:33 +0200 Subject: Method parameters inspect Example: def m(a, b=nil, *c, d:, e: nil, **rest, &block) end p method(:m) #=> #, *c, d:, e: , **rest, &block) ...> --- proc.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'proc.c') diff --git a/proc.c b/proc.c index 2dc625b41e..e37ac1ceb3 100644 --- a/proc.c +++ b/proc.c @@ -2827,7 +2827,64 @@ method_inspect(VALUE method) } // parameter information - // TODO + { + VALUE params = rb_method_parameters(method); + VALUE pair, name, kind; + int arg_num = 1; + const VALUE req = ID2SYM(rb_intern("req")); + const VALUE opt = ID2SYM(rb_intern("opt")); + const VALUE keyreq = ID2SYM(rb_intern("keyreq")); + const VALUE key = ID2SYM(rb_intern("key")); + const VALUE rest = ID2SYM(rb_intern("rest")); + const VALUE keyrest = ID2SYM(rb_intern("keyrest")); + const VALUE block = ID2SYM(rb_intern("block")); + const VALUE nokey = ID2SYM(rb_intern("nokey")); + + rb_str_buf_cat2(str, "("); + + for (int i = 0; i < RARRAY_LEN(params); i++) { + pair = RARRAY_AREF(params, i); + kind = RARRAY_AREF(pair, 0); + name = RARRAY_AREF(pair, 1); + // FIXME: in tests it turns out that kind, name = [:req] produces name to be false. Why?.. + if (NIL_P(name) || name == Qfalse) { + // FIXME: can it be reduced to switch/case? + if (kind == req || kind == opt) { + name = rb_sprintf("arg%d", arg_num); + arg_num++; + } else if (kind == rest || kind == keyrest) { + name = rb_str_new2(""); + } else if (kind == block) { + name = rb_str_new2("block"); + } else if (kind == nokey) { + name = rb_str_new2("nil"); + } + } + + if (kind == req) { + rb_str_catf(str, "%"PRIsVALUE, name); + } else if (kind == opt) { + rb_str_catf(str, "%"PRIsVALUE"=", name); + } else if (kind == keyreq) { + rb_str_catf(str, "%"PRIsVALUE":", name); + } else if (kind == key) { + rb_str_catf(str, "%"PRIsVALUE": ", name); + } else if (kind == rest) { + rb_str_catf(str, "*%"PRIsVALUE, name); + } else if (kind == keyrest) { + rb_str_catf(str, "**%"PRIsVALUE, name); + } else if (kind == block) { + rb_str_catf(str, "&%"PRIsVALUE, name); + } else if (kind == nokey) { + rb_str_buf_cat2(str, "**nil"); + } + + if (i < RARRAY_LEN(params) - 1) { + rb_str_buf_cat2(str, ", "); + } + } + rb_str_buf_cat2(str, ")"); + } { // source location VALUE loc = rb_method_location(method); -- cgit v1.2.3