Proposal - show_source-ish command
Naming Options
show-source- I prefer this because:
- I used to use
prya lot so I'm used to it. - Basically impossible to conflict with user's variable/method name.
- I used to use
- I prefer this because:
show_source- something else
- If we go for this option, a one-word name would probably be better.
- But to get people onboard more easily, I think an alias to
show-sourceorshow_sourcemay still be needed.
Interface
show-source- same asshow-source selfshow-source obj- show the object's classshow-source obj.method- show the method's definitionshow-source class- show class definitionshow-source class#method- show the method's definitionshow-source class.method- show the method's definition
Output Format
pry
[2] pry(main)> show-source Bar#foo
From: foo.rb:6:
Owner: Bar
Visibility: public
Signature: foo()
Number of lines: 3
def foo
super
end
irb
irb(main):001:0> show_source "Bar#foo"
From: foo.rb:6
def foo
super
end
=> nil
You can see that pry provides a nicer output. But we can probably start from something simpler, like irb's.
Support for super
pry's show-source also supports using -s option to access the method's super definition.
class Foo
def foo; end
end
class Bar < Foo
def foo
super
end
end
[2] pry(main)> show-source Bar#foo
Owner: Bar
Visibility: public
Signature: foo()
Number of lines: 3
def foo
super
end
[3] pry(main)> show-source Bar#foo -[]()s
From: foo.rb:2:
Owner: Foo
Visibility: public
Signature: foo()
Number of lines: 1
def foo; end
You can even use multiple s to access farther definitions. And it'd print a warning when there's no more superclasses.
[4] pry(main)> show-source Bar#foo -ss
Error: No superclass found for #<UnboundMethod: Bar#foo() foo.rb:6>
(I think irb's show_source currently doesn't support this feature.)
I believe this is something we should support from the beginning. But currently the debugger dosn't take command options like -opt and I don't think we'll support that in the near future. So we need to come up with another way to do it.
Perhaps show-source Bar#foo level:[num] ?
show-source Bar#foo level:0- showsBar#fooshow-source Bar#foo level:1- showsFoo#foo
Looking for Feedback
- Name?
- Is there any options from either
pryorirb'sshow*sourcecommand should also be considered? - Anything to add/remove from the output?
Name?
I like show-source; what about a shortcut? Like $.
Anything to add/remove from the output?
For super, it would be useful to see a parent of the method:
Owner: Bar
Parent: Foo
Visibility: public
Signature: foo()
Number of lines: 3
That could eliminate the need of -s, probably (never used it with Pry).
I don't want to introduce foo-bar style naming for consistency.
list obj#method for example?
For super, it would be useful to see a parent of the method:
Yeah it's good to have parent info. But there could be multiple levels of super, so I think something like level: is still needed.
list obj#method
I think it's great 👍
What about the super option? Do you accept list Foo#bar level:2 or list Foo#bar s:2?
list Foo#bar has pros/cons.
pros.
- We don't need to introduce new command (and we can make alias like
show[-_]sourceand so on cons. - It is difficult to define the behavior
- how many lines? (whole of method def or 10 lines?)
- if it is not whole lines, what happens on next
listcommand? continue to show theFoo#bar? - and how to show the source code on the current frame?
The difficulties can be solved with pager configuration like pry (and git command for example).
Note that pry doesn't use pager for $ foo#bar, but use it on printing the value.
pry's show-source only prints the definition of method, but maybe list Foo#bar shows the source code lines beginning from Foo#bar (with other method lines).
Do you want to see completely same with pry? (and with headers?)
If you can accept alias like show_source, it's essentially having a new command to users. In that case, I think adding that functionality to list command makes things unnecessarily complicated.
So to me, the options are:
- Baking that function into
listcommand, with no alias. - Or, having a separate command and keeping
listas it is.
I prefer having a show[-_]source command and replicate what pry has. This will save us the effort to redefine list's behavior.
Other things pry's cmd can do:
$ ModuleOrClassand it shows the whole thing. There's also-afor "all" which I think would do so even if you say#method- partial evaluation:
$ obj.m1.m2.m3evaluatesobj.m1.m2and shows the appropriate source for m3 based on receiver
Perhaps differently... but there's also whereami and it takes --method, --class, and --file args to show the source around the current frame at multiple levels.
does pry has show-XXX other than source?
$ ModuleOrClass and it shows the whole thing.
# C.rb
class C
FIRST = true
end
# target.rb
[1] pry(main)> $ C
From: target.rb:4
Class name: C
Number of lines: 17
class C
def foo = 1
end
class D
end
class C
def bar = 2
end
class E
end
class C
def baz = 3
end
binding.pry
$ pry -v
Pry version 0.14.1 on Ruby 3.1.2
$ ruby target.rb
From: /mnt/c/ko1/src/rb/ruby-debug/target.rb:22 :
17:
18: class C
19: def baz = 3
20: end
21:
=> 22: binding.pry
23:
24: __END__
25:
26: $0 = 'P '; start_tm = Time.now; ps = 2.times.map do |i|
27: fork do
[1] pry(main)> $ C
From: target.rb:4
Class name: C
Number of lines: 17
class C
def foo = 1
end
class D
end
class C
def bar = 2
end
class E
end
class C
def baz = 3
end
Does not support open classes? I'm not sure we can support it...
The two features I use the most from Pry are show-source (via the alias $), and ls (sometimes with --grep). As someone who installs pry on most of my projects, adding support for show-source (preferably including the alias) to debug would make it really compelling to switch over.
As far as supporting open classes, from trying out some scenarios in Pry, it seems to take a "best guess" approach when it comes to surfacing places a class is re-opened, but it is certainly not perfect. However, I think this is acceptable behavior.
2 years on, and still the only thing I miss daily from the pry days 😅
Were there any more discussions somewhere?
Not exactly the same, but with the latest debug and IRB, you can use RUBY_DEBUG_IRB_CONSOLE=1 env var to make IRB the debug's default console. And then you can use IRB's show_source (and other commands) in addition to the debug's commands in your debugging sessions.