summaryrefslogtreecommitdiff
path: root/proc.c
diff options
context:
space:
mode:
authorzverok <zverok.offline@gmail.com>2019-10-27 12:39:33 +0200
committerKoichi Sasada <ko1@atdot.net>2019-11-20 13:42:56 +0900
commit4b583cff97025394fab4a014a2a8606dfb557475 (patch)
tree47c30089de12ea722acc0b5139dfc7af2c8f649d /proc.c
parentda0d7211aa85b90f2246e2d9abfe08105f7ddedb (diff)
Method parameters inspect
Example: def m(a, b=nil, *c, d:, e: nil, **rest, &block) end p method(:m) #=> #<Method: m(a, b=<default>, *c, d:, e: <default>, **rest, &block) ...>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/2618
Diffstat (limited to 'proc.c')
-rw-r--r--proc.c59
1 files changed, 58 insertions, 1 deletions
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"=<default>", name);
+ } else if (kind == keyreq) {
+ rb_str_catf(str, "%"PRIsVALUE":", name);
+ } else if (kind == key) {
+ rb_str_catf(str, "%"PRIsVALUE": <default>", 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);