Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@kitlangton
Copy link
Member

A useful method for debugging/teaching/learning. putStrLn is a bit difficult to use in an ad hoc manner as it requires a string, so you have to write .tap(arg => console.putStrLn(a.toString)), which is a bit of a mouthful when you just want to peek at the current value.

I've implemented debug and debug(prefix: String) and related methods for easily printing out the value. All it does is tap and putStrLn after calling toString, also optionally prefixing the output with the specified message.

object Example extends App {
  val effect = random.nextInt.flatMap {
    case i if i % 3 == 0 => ZIO.fail(s"OH NO $i")
    case i => UIO(i)
  }

  def run(args: List[String]) =
    ZIO
      .replicateParM(10)(effect.debugBoth("Cool"))
      .exitCode
}

This will output:

Cool: -1522815466
Cool: 541453234
Cool: -482366690
Cool: 1597855825
Cool: -507234278
Cool: 364903378
Cool: 594767090
Cool <FAIL>: OH NO 811767111
Cool <FAIL>: OH NO -2115255561
Cool <FAIL>: OH NO 1561730550

@kitlangton kitlangton changed the title implement ZIO#debug and related methods Implement ZIO#debug and related methods Mar 20, 2021
@adamgfraser
Copy link
Contributor

I think these should probably use the live console so you don't have to change your method signatures when you use them for debugging purposes.

@adamgfraser
Copy link
Contributor

Other question is whether we want it to be configurable regarding whether it prints and want to use a macro so we can eliminate the code if it isn't enabled.

@kitlangton
Copy link
Member Author

I think these should probably use the live console so you don't have to change your method signatures when you use them for debugging purposes.

Oh yeah. That's a great idea. 😄 I'll do this.

Other question is whether we want it to be configurable regarding whether it prints and want to use a macro so we can eliminate the code if it isn't enabled.

I've seen some examples of this with Scala 3, but I'm not quite sure how to achieve it within the context of a library. Not sure where we'd put the shouldDebug config variable that could be read at compile time. Do you know of any libraries that do something like this?

* Taps the effect, printing the result of calling `.toString` on the value
*/
final def debug: ZIO[R, E, A] =
self.tapBoth(
Copy link
Contributor

Choose a reason for hiding this comment

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

I would how we should handle a defect here? It seems like it could be useful for debugging but the full cause can be extremely long. Maybe we could just show the first cause in that case?

Copy link
Member Author

Choose a reason for hiding this comment

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

Something like?

  /**
   * Taps the effect, printing the result of calling `.toString` on the value
   * or the error.
   */
  final def debug: ZIO[R, E, A] =
    self
      .tapCause(cause =>
        cause.find {
          case Cause.Interrupt(fiberId) => s"<INTERRUPT> by $fiberId"
          case Cause.Die(throwable)     => s"<DIE> $throwable"
          case Cause.Fail(error)        => s"<FAIL> $error"
        }.fold(UIO.unit) { message =>
          UIO(println(message))
        }
      )
      .tap(value => UIO(println(value)))

  /**
   * Taps the effect, printing the result of calling `.toString` on the value.
   * Prefixes the output with the given message.
   */
  final def debug(prefix: => String): ZIO[R, E, A] =
    self
      .tapCause(cause =>
        cause.find {
          case Cause.Interrupt(fiberId) => s"$prefix: <INTERRUPT> by $fiberId"
          case Cause.Die(throwable)     => s"$prefix: <DIE> $throwable"
          case Cause.Fail(error)        => s"$prefix: <FAIL> $error"
        }.fold(UIO.unit) { message =>
          UIO(println(message))
        }
      )
      .tap(value => UIO(println(s"$prefix: $value")))

Copy link
Member Author

Choose a reason for hiding this comment

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

Also, I wouldn't mind not keeping it as it is, and letting the runtime render dies.

@adamgfraser
Copy link
Contributor

Yes, I'm not sure either. We can always optimize that later.

@adamgfraser adamgfraser merged commit 6a7eb96 into zio:master Mar 26, 2021
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.

2 participants