From 9b52bacc62c3db13ea18fa5ea4d9b9a92b5fcb86 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 21 Nov 2019 02:14:20 +0900 Subject: Refined inspection of argument forwarding --- proc.c | 51 ++++++++++++++++++++++++++++++++++++------------ test/ruby/test_method.rb | 6 ++++-- 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 -- cgit v1.2.3