Skip to content

Add pretty_print methods to Result and Maybe #189

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

Closed
wants to merge 1 commit into from

Conversation

paul
Copy link

@paul paul commented May 16, 2025

Adds #pretty_print to Result and Maybe, so PP looks good.

Examples:

>> pp M::Success()
Success()

>> pp M::Success(User.first)
Success(
 #<User:0x00007f414e3584a0
  id: 1,
  email: [FILTERED],
  name: "Paul",
  staff: true,
  automated_actor: false,
  settings: {},
  auth_uid: nil,
  auth_profile: nil,
  created_at: "2025-05-13 21:34:12.784955000 +0000",
  updated_at: "2025-05-13 21:34:12.784955000 +0000",
  discarded_at: nil>)

>> pp result.to_monad
Failure(
 #<Dry::Validation::Result
 {now: 2025-05-16 14:52:40.354675084 UTC +00:00}
 errors={chat: ["is missing"], user: ["is missing"], user_message: ["is missing"]}>)

>> pp M::Some(User.first)
Some(
 #<User:0x00007f414e35a8e0
  id: 1,
  email: [FILTERED],
  name: "Paul Sadauskas",
  staff: true,
  automated_actor: false,
  settings: {},
  auth_uid: nil,
  auth_profile: nil,
  created_at: "2025-05-13 21:34:12.784955000 +0000",
  updated_at: "2025-05-13 21:34:12.784955000 +0000",
  discarded_at: nil>)

>> pp M::None()
None

Also, Pry and IRB leverage PP for their output, and even can color it, so this lets it color the monads, and the contents of the monads:

Before:

image

After:

image

@flash-gordon
Copy link
Member

I'm positive about this, but can you make it an extension?

@paul
Copy link
Author

paul commented May 20, 2025

I can, but I'm curious as to why. Here's my case for it not being an extension:

  1. It provides a nicer out-of-the-box DX for newcomers, or people using then through another gem without realizing it. If its an extension, then people need to know that 1) it exists and 2) they have to explicitly enable it. Plus, that's made all that much harder because there's no documentation about extensions. I've been using Dry::Monads in projects for many years, and I didn't even realize it had extensions.
  2. It doesn't "cost" anything. I see the point of extensions for optional functionality that might change behavior, or pull in expensive dependencies. But this implements 4 methods in 30 lines of code. The presence these methods being defined but never used costs a minuscule amount of memory and no processing time.

If you still want it as an extension, that's fine, its your project. I'm skeptical of the tradeoff involved, and urge you to reconsider, or at least explain your decision.

@flash-gordon
Copy link
Member

they have to explicitly enable it

I don't have strong feelings if it's enabled by default, I just don't like when code is cluttered with significantly different things. My suggestion is trying to extract representation-related stuff to a separate file, similarly to how inspection is handled in dry-types. That said, it's not obvious to me which approach is better in the long run, I'll play around with extension to see if I actually like it. I'll send a PR later today

@timriley
Copy link
Member

Thanks for putting this together, @paul! And thanks for taking care of it, @flash-gordon :)

FWIW, I'd love to have the pretty printing support enabled by default. It's a great example of how we can make our gems better to interact with, and one I'd love to carry over to the rest of our gems too. ❤️

flash-gordon added a commit that referenced this pull request Jun 23, 2025
It is enabled by default
flash-gordon added a commit that referenced this pull request Jun 23, 2025
It is enabled by default
@flash-gordon
Copy link
Member

@paul @timriley yeah, thanks for bringing it up. I spent some time fruitlessly trying to bend pp to print

Some[
  1,
  2,
  ... # many more values
  100
]

Instead of its defaults:

Some(
 [1,
  2,
  # ...
  100])

Alas, it turned out to be less trivial so I gave up.

I've finished the implementation for all monads in an auto-loaded extensions #190 I think it's good to go. If you folks don't have objections, I'll releases it later today

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

Successfully merging this pull request may close these issues.

3 participants