debug icon indicating copy to clipboard operation
debug copied to clipboard

Proposal - show_source-ish command

Open st0012 opened this issue 3 years ago • 13 comments

Naming Options

  • show-source
    • I prefer this because:
      1. I used to use pry a lot so I'm used to it.
      2. Basically impossible to conflict with user's variable/method name.
  • 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-source or show_source may still be needed.

Interface

  • show-source - same as show-source self
  • show-source obj - show the object's class
  • show-source obj.method - show the method's definition
  • show-source class - show class definition
  • show-source class#method - show the method's definition
  • show-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 - shows Bar#foo
  • show-source Bar#foo level:1 - shows Foo#foo

Looking for Feedback

  • Name?
  • Is there any options from either pry or irb's show*source command should also be considered?
  • Anything to add/remove from the output?

st0012 avatar Feb 12 '22 13:02 st0012

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

palkan avatar Feb 15 '22 14:02 palkan

I don't want to introduce foo-bar style naming for consistency. list obj#method for example?

ko1 avatar Feb 21 '22 19:02 ko1

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?

st0012 avatar Feb 22 '22 16:02 st0012

list Foo#bar has pros/cons.

pros.

  • We don't need to introduce new command (and we can make alias like show[-_]source and 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 list command? continue to show the Foo#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).

ko1 avatar Mar 20 '22 23:03 ko1

Note that pry doesn't use pager for $ foo#bar, but use it on printing the value.

ko1 avatar Mar 20 '22 23:03 ko1

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?)

ko1 avatar Mar 20 '22 23:03 ko1

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:

  1. Baking that function into list command, with no alias.
  2. Or, having a separate command and keeping list as 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.

st0012 avatar Mar 21 '22 11:03 st0012

Other things pry's cmd can do:

  • $ ModuleOrClass and it shows the whole thing. There's also -a for "all" which I think would do so even if you say #method
  • partial evaluation: $ obj.m1.m2.m3 evaluates obj.m1.m2 and 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.

zenspider avatar Jul 08 '22 19:07 zenspider

does pry has show-XXX other than source?

ko1 avatar Sep 16 '22 08:09 ko1

$ 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...

ko1 avatar Sep 16 '22 08:09 ko1

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.

sambostock avatar Oct 20 '22 01:10 sambostock

2 years on, and still the only thing I miss daily from the pry days 😅

Were there any more discussions somewhere?

miharekar avatar Mar 26 '24 09:03 miharekar

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.

st0012 avatar Apr 04 '24 15:04 st0012