From: zverok.offline@... Date: 2019-03-11T15:20:02+00:00 Subject: [ruby-core:91786] [Ruby trunk Feature#14145] Proposal: Better Method#inspect Issue #14145 has been updated by zverok (Victor Shepelev). I'd like to address this line from the dev log: > ko1: I���m against to show the name of parameters. we only need line no. doesn���t it? > matz: ask the original author. I believe that I've already provided a use-case of my point of view, let me just repeat it: > I mean, what I had in mind was like "I am trying something in IRB/Debugger, and want to quickly experiment". This flow seems somehow natural to me: ```ruby obj = SomeNewLib.call_how_readme_shows obj.class # => SomeClass obj.methods # => [:foo, :bar] obj.method(:bar) # => # Oh! obj.bar(3) ``` That's simple, **same-context flow**, which allows quick "pokin around". The source location is NOT "same context" (you ask it to switch to the editor or fetch source some way), so for me, it doesn't need to be "on the fingertips" (read: in `#inspect` output). @ko1 doesn't it sound reasonable to you? **Generally speaking** I believe that `#inspect`'s design goal is to provide enough, but not too much, information to understand "what is this object and how it can be used in the current context". I believe that `` follows this design goal -- "I know what I can do next with this object". Next, I don't think "`Method` should have source location, because `Proc` has": for proc, it is typically the **only** way to tell one proc from another -- "it is a proc from that file", that's why "always visible" source location is important. For method, we have other means of identification and telling one from another (name, owner, receiver), and adding source location to it will make `#inspect`'s output just less readable. ---------------------------------------- Feature #14145: Proposal: Better Method#inspect https://bugs.ruby-lang.org/issues/14145#change-77061 * 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) # => # # after: some_interesting_object.method(:foo) # => # ``` 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}"} = " when :keyreq then "#{name || "kw#{i+1}"}:" when :key then "#{name || "kwparam#{i+1}"}: " 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) # => # # Ruby method, proper param names CGI.method(:escape) # => # Addressable::URI.method(:parse) # => # Addressable::URI.method(:join) => # # We can't extract default values, but at least we can say they are there Addressable::URI.method(:heuristic_parse) # => #)> ``` 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/ Unsubscribe: