ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: zverok.offline@gmail.com
To: ruby-core@ruby-lang.org
Subject: [ruby-core:95570] [Ruby master Feature#14145] Proposal: Better Method#inspect
Date: Sun, 27 Oct 2019 10:45:54 +0000 (UTC)	[thread overview]
Message-ID: <redmine.journal-82351.20191027104553.205786d49c095bab@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-14145.20171130104208@ruby-lang.org

Issue #14145 has been updated by zverok (Victor Shepelev).


This PR provides method parameters inspect: https://github.com/ruby/ruby/pull/2618
Implementation is most probably not optimal (to say the least), I am ready to fix it by comments. At least the tests and implementation should handle all possible cases.

Examples:

```ruby
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) ...>

# Internal classes with param names not known:
p Array.instance_method(:slice)
#=> #<UnboundMethod: Array#slice(*)>
p Array.instance_method(:grep)
#=> #<UnboundMethod: Array(Enumerable)#grep(arg1)>
```

----------------------------------------
Feature #14145: Proposal: Better Method#inspect
https://bugs.ruby-lang.org/issues/14145#change-82351

* Author: zverok (Victor Shepelev)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
The idea: When investigating (in example scripts, debugger or console) the library you are unfamiliar with, Ruby's reflection is very useful mechanism to understand "what it can": classes, modules, their constants, methods and so on.
I propose to expose a bit more information Ruby has internally in `Method#inspect`:


```ruby
# before:
some_interesting_object.method(:foo) # => #<Method Klass#foo>
# after:
some_interesting_object.method(:foo) # => #<Method Klass#foo(first_arg, *other_args, keyword_arg:)>
```

Dead-naive implementation:

```ruby
class Method
  def signature
    recv = case receiver
    when Module
      "#{receiver.name}."
    else
      "#{receiver.class}#"
    end
    parameters.map.with_index { |(type, name), i|
      case type
      when :req then "#{name || "param#{i+1}"}"
      when :opt then "#{name || "param#{i+1}"} = <default>"
      when :keyreq then "#{name || "kw#{i+1}"}:"
      when :key then "#{name || "kwparam#{i+1}"}: <default>"
      when :rest then "*#{name || "rest"}"
      when :keyrest then "**#{name || "kwrest"}"
      end
    }.join(', ').prepend("#{recv}#{name}(") << ")"
  end

  def inspect
    "#<#{self.class.name} #{signature}>"
  end
end

```

This works "sub-optimal" for methods implemented in C, yet pretty decently for Ruby-implemented methods:

```ruby
# C method, default param names
[1,2,3].method(:at)
# => #<Method Array#at(param1)>

# Ruby method, proper param names
CGI.method(:escape)
# => #<Method CGI.escape(string)>
Addressable::URI.method(:parse)
# => #<Method Addressable::URI.parse(uri)>
Addressable::URI.method(:join)
 => #<Method Addressable::URI.join(*uris)>

# We can't extract default values, but at least we can say they are there
Addressable::URI.method(:heuristic_parse)
# => #<Method Addressable::URI.heuristic_parse(uri, hints = <default>)>
```

If the proposal is accepted, I am ready to implement it properly in C (for all callable objects: `Method`, `UnboundMethod`, `Proc`)



-- 
https://bugs.ruby-lang.org/

  parent reply	other threads:[~2019-10-27 10:46 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <redmine.issue-14145.20171130104208@ruby-lang.org>
2017-11-30 10:42 ` [ruby-core:84004] [Ruby trunk Feature#14145] Proposal: Better Method#inspect zverok.offline
2017-11-30 12:23 ` [ruby-core:84005] " shevegen
2017-11-30 14:39 ` [ruby-core:84007] " hanmac
2017-11-30 15:41 ` [ruby-core:84009] " zverok.offline
2017-12-04  7:54 ` [ruby-core:84076] " ko1
2017-12-04  8:15 ` [ruby-core:84077] " hanmac
2017-12-04 11:35 ` [ruby-core:84085] " zverok.offline
2018-10-27 23:56 ` [ruby-core:89585] " guilhermekbsa
2018-10-28  6:47 ` [ruby-core:89596] " eregontp
2018-10-28  9:10 ` [ruby-core:89599] " Ruby-Lang
2018-11-06 23:36 ` [ruby-core:89738] " keystonelemur
2018-11-07  7:06 ` [ruby-core:89743] " nobu
2018-11-07  8:35 ` [ruby-core:89746] " keystonelemur
2019-01-10  5:02 ` [ruby-core:90967] " matz
2019-01-11  1:49 ` [ruby-core:91009] " ko1
2019-03-11  6:30 ` [ruby-core:91754] " ko1
2019-03-11 15:20 ` [ruby-core:91786] " zverok.offline
2019-03-13 20:21 ` [ruby-core:91819] " eregontp
2019-03-14  6:45 ` [ruby-core:91827] " duerst
2019-06-13  5:44 ` [ruby-core:93086] " nobu
2019-07-14  7:01 ` [ruby-core:93747] [Ruby master " ko1
2019-07-14 13:39 ` [ruby-core:93760] " zn
2019-07-14 17:58 ` [ruby-core:93762] " eregontp
2019-07-30  7:07 ` [ruby-core:94025] " ko1
2019-10-04 17:57 ` [ruby-core:95229] " richard.schneeman+ruby-lang
2019-10-27 10:45 ` zverok.offline [this message]
2019-11-19  9:05 ` [ruby-core:95886] " ko1
2019-11-19 18:42 ` [ruby-core:95887] " zverok.offline
2019-11-20  0:41 ` [ruby-core:95888] " zverok.offline
2019-11-20  4:43 ` [ruby-core:95891] " ko1

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=redmine.journal-82351.20191027104553.205786d49c095bab@ruby-lang.org \
    --to=ruby-core@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).