debug icon indicating copy to clipboard operation
debug copied to clipboard

Add hook for customizing the debug representation of an object

Open amomchilov opened this issue 2 years ago • 8 comments

This PR depends on the changes in #1004. Only this last commit of this PR is unique to this change.

Description

I propose we add a hook method that developers can implement in their classes to customize the structural representation of their objects in a debugger. Used judiciously, this has the potential to really improve the clarify of certain types of objects.

I found it particularly useful for container-like objects, like OpenStruct and ActionController::StrongParameters.

Before After
Screenshot 2023-07-28 at 10 12 48 AM Screenshot 2023-07-28 at 10 17 11 AM
example.rb
require 'ostruct'
require 'action_controller'

class OpenStruct
  # Use our hash representation directly, to hide the `@table` clutter.
  def debug_representation = to_h
end

class ActionController::Parameters
  # Flatten the parameters right into the top level of this object's representation.
  def debug_representation
    {
      :@permitted => @permitted,
      :@logging_context => @logging_context,
      **@parameters
    }
  end
end

line = OpenStruct.new(
  start_point: OpenStruct.new(x: 1, y: 2),
  end_point: OpenStruct.new(x: 3, y: 4),
)

params = ActionController::Parameters.new(
  {
    person: {
      name: "Francesco",
      age:  22,
      role: "admin"
    }
  }
)

I chose the spelling #debug_representation, because it's clear and to-the-point, but it's open to ideas.

amomchilov avatar Jul 28 '23 14:07 amomchilov

A big +1 for this feature. This would be great. Surprised this wasn't in from the start. Being able to control what's on the debug inspector without overloading to_s and inspect (which may be needed for something else) seems like a very sensible idea.

When are some of these PRs going to get applied? It's been quiet the last few months...

jabamaus avatar Sep 21 '23 11:09 jabamaus

Could you give us the API specification?

ko1 avatar Sep 25 '23 07:09 ko1

I'm not sure what the content of this PR exactly is but what I'd simply like is the ability to define a method on my objects called something like "to_rdbg" (or something I don't really mind) and have rdbg call that preferentially to to_s/inspect. In this way I could have to_s/inspect freed up for just my use and control over what appears in the debug window.

jabamaus avatar Sep 26 '23 10:09 jabamaus

@jabamaus @ko1 Ignore the first few commits that come from other branches. This is the relevant commit to this PR: https://github.com/ruby/debug/pull/1005/commits/89427979a16497d27e2f4021ae84f094768627e1

@ko1 The API is really simple: If your object responds to #debug_representation, the debugger will call it and use the result as the representation of your object.

Look closely at the PR description, I put an example.rb that shows an examples for OpenStruct and ActionController::Parameters.

amomchilov avatar Sep 26 '23 22:09 amomchilov

Thanks @amomchilov that makes it easier to follow. What will happen if the object being inspected is a BasicObect? BasicObject does not implement respond_to?

jabamaus avatar Sep 27 '23 05:09 jabamaus

@jabamaus Please have a look at the implementation. It always uses the Kernel implementation of respond_to?, so that it works even on BasicObject, or any objects with a bad override of #respond_to?.

amomchilov avatar Sep 27 '23 17:09 amomchilov

@ko1 The API is really simple: If your object responds to #debug_representation, the debugger will call it and use the result as the representation of your object.

Could you explain the specification of #debug_representation?

ko1 avatar Oct 02 '23 07:10 ko1