Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hook for customizing the debug representation of an object #1005

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

amomchilov
Copy link

@amomchilov amomchilov commented Jul 28, 2023

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.

@debug_representation = debug_representation
end

def debug_representation
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it should take unused rest args, in case any need to be added in the future?

Suggested change
def debug_representation
def debug_representation(*, **)

@amomchilov amomchilov changed the title Debug representation hook Add hook for customizing the debug representation of an object Jul 28, 2023
@jabamaus
Copy link

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

@ko1
Copy link
Collaborator

ko1 commented Sep 25, 2023

Could you give us the API specification?

@jabamaus
Copy link

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.

@amomchilov
Copy link
Author

@jabamaus @ko1 Ignore the first few commits that come from other branches. This is the relevant commit to this PR: 8942797

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

@jabamaus
Copy link

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?

@amomchilov
Copy link
Author

@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?.

@ko1
Copy link
Collaborator

ko1 commented Oct 2, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants