aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2019-11-21 02:14:20 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2019-11-21 02:18:13 +0900
commit9b52bacc62c3db13ea18fa5ea4d9b9a92b5fcb86 (patch)
treeb57ad7a90e4359b25339091c52b3f061917076c2
parentf835a74da45f95073d12f84c3b8de9fb2f1e9ff6 (diff)
downloadruby-9b52bacc62c3db13ea18fa5ea4d9b9a92b5fcb86.tar.gz
Refined inspection of argument forwarding
-rw-r--r--proc.c51
-rw-r--r--test/ruby/test_method.rb6
2 files changed, 43 insertions, 14 deletions
diff --git a/proc.c b/proc.c
index 9859116baf..e0ce44297c 100644
--- a/proc.c
+++ b/proc.c
@@ -2838,6 +2838,7 @@ method_inspect(VALUE method)
const VALUE keyrest = ID2SYM(rb_intern("keyrest"));
const VALUE block = ID2SYM(rb_intern("block"));
const VALUE nokey = ID2SYM(rb_intern("nokey"));
+ int forwarding = 0;
rb_str_buf_cat2(str, "(");
@@ -2850,30 +2851,56 @@ method_inspect(VALUE method)
// FIXME: can it be reduced to switch/case?
if (kind == req || kind == opt) {
name = rb_str_new2("_");
- } else if (kind == rest || kind == keyrest) {
+ }
+ else if (kind == rest || kind == keyrest) {
name = rb_str_new2("");
- } else if (kind == block) {
+ }
+ else if (kind == block) {
name = rb_str_new2("block");
- } else if (kind == nokey) {
+ }
+ else if (kind == nokey) {
name = rb_str_new2("nil");
}
}
if (kind == req) {
rb_str_catf(str, "%"PRIsVALUE, name);
- } else if (kind == opt) {
+ }
+ else if (kind == opt) {
rb_str_catf(str, "%"PRIsVALUE"=...", name);
- } else if (kind == keyreq) {
+ }
+ else if (kind == keyreq) {
rb_str_catf(str, "%"PRIsVALUE":", name);
- } else if (kind == key) {
+ }
+ else if (kind == key) {
rb_str_catf(str, "%"PRIsVALUE": ...", name);
- } else if (kind == rest) {
- rb_str_catf(str, "*%"PRIsVALUE, name);
- } else if (kind == keyrest) {
+ }
+ else if (kind == rest) {
+ if (name == ID2SYM('*')) {
+ forwarding = 1;
+ rb_str_cat_cstr(str, "...");
+ }
+ else {
+ 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) {
+ }
+ else if (kind == block) {
+ if (name == ID2SYM('&')) {
+ if (forwarding) {
+ rb_str_set_len(str, RSTRING_LEN(str) - 2);
+ }
+ else {
+ rb_str_cat_cstr(str, "...");
+ }
+ }
+ else {
+ rb_str_catf(str, "&%"PRIsVALUE, name);
+ }
+ }
+ else if (kind == nokey) {
rb_str_buf_cat2(str, "**nil");
}
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index 38bcaba622..edd1da368c 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -555,6 +555,7 @@ class TestMethod < Test::Unit::TestCase
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyrest, :o]], method(:mk7).parameters)
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyreq, :e], [:key, :f], [:keyrest, :o]], method(:mk8).parameters)
assert_equal([[:nokey]], method(:mnk).parameters)
+ # pending
assert_equal([[:rest, :*], [:block, :&]], method(:mf).parameters)
end
@@ -580,6 +581,7 @@ class TestMethod < Test::Unit::TestCase
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyrest, :o]], self.class.instance_method(:mk7).parameters)
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyreq, :e], [:key, :f], [:keyrest, :o]], self.class.instance_method(:mk8).parameters)
assert_equal([[:nokey]], self.class.instance_method(:mnk).parameters)
+ # pending
assert_equal([[:rest, :*], [:block, :&]], self.class.instance_method(:mf).parameters)
end
@@ -657,7 +659,7 @@ class TestMethod < Test::Unit::TestCase
assert_include(method(:mk7).inspect, "(a, b=..., *c, d, **o)")
assert_include(method(:mk8).inspect, "(a, b=..., *c, d, e:, f: ..., **o)")
assert_include(method(:mnk).inspect, "(**nil)")
- assert_include(method(:mf).inspect, "(**, &&)")
+ assert_include(method(:mf).inspect, "(...)")
end
def test_unbound_method_parameters_inspect
@@ -682,7 +684,7 @@ class TestMethod < Test::Unit::TestCase
assert_include(self.class.instance_method(:mk7).inspect, "(a, b=..., *c, d, **o)")
assert_include(self.class.instance_method(:mk8).inspect, "(a, b=..., *c, d, e:, f: ..., **o)")
assert_include(self.class.instance_method(:mnk).inspect, "(**nil)")
- assert_include(self.class.instance_method(:mf).inspect, "(**, &&)")
+ assert_include(self.class.instance_method(:mf).inspect, "(...)")
end
def test_public_method_with_zsuper_method