Skip to content

Add a shorter macro for println!("{:?}", foo) #12015

Closed

Description

@SimonSapin

When print-debugging, I find myself writing println!("{:?}", some expression) a lot. I wish I didn’t have to write the "{:?}" part, which is always the same. For temporary debugging-only code, I don’t care about making the output pretty, I only want to see what’s going on.

So I’d like to have a new macro added wherever println!() is defined:

macro_rules! dump(
    ($a: expr) => { println!("{:?}", $a) }
    ($a: expr, $b: expr) => { println!("{:?} {:?}", $a, $b) }
    ($a: expr, $b: expr, $c: expr) => { println!("{:?} {:?} {:?}", $a, $b, $c) }
    ($a: expr, $b: expr, $c: expr, $d: expr) => { println!("{:?} {:?} {:?} {:?}", $a, $b, $c, $d) }
)

… with this pattern repeated to however many arguments is appropriate. (Although, worst case, one can always pass a tuple.) Or is there a way to write this completely generic over the number of arguments?

Activity

  1. sfackler commented on Feb 3, 2014

    @sfackler
    Member

    You might be able to make it generic in the number of arguments with concat!. Writing it as a procedural macro would also do it.

  2. alexcrichton commented on Feb 3, 2014

    @alexcrichton
    Member

    You can make it generic with something like:

    macro_rules! dump(                                                   
        ($($a:expr),*) => {                                              
            println!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
        }                                                                
    )                                                                    

    We've seen some recent pushback from including more {:?} instances in the standard library, so this may not have a great place in there (see #11793). A macro like this would be great for beginners, however.

  3. SimonSapin commented on Feb 3, 2014

    @SimonSapin
    ContributorAuthor

    @alexcrichton that seems mostly orthogonal. Any opinion on whether this, a macro for quick print-style debugging, is something we want at all?

  4. alexcrichton commented on Feb 3, 2014

    @alexcrichton
    Member

    I personally feel that a small debugging macro is something that'll be home-grown on a per-repo basis. The hard part right now is that macro_rules is behind a feature gate. My own personal opinion is to not include something like this in libstd, but to certainly document it in the macro tutorial or in the documentation somewhere (just as an example).

  5. SimonSapin commented on Feb 3, 2014

    @SimonSapin
    ContributorAuthor

    Print-style debugging IMO should be quick, ugly, and temporary. In particular, "temporary" means that I do not want debugging-only code to lie around in my code for longer than a few change/compile/test cycles. It should never end up in version control.

    Given this, an example macro in the tutorial is really not that helpful, as println!("{:?}", foo) is still quicker.

    This is all personal opinions of course, but anything that is not in the prelude (or equivalent) doesn’t cut it for me.

  6. added 2 commits that reference this issue on Feb 19, 2014
    778ce62
    1678300
  7. dobkeratops commented on Apr 22, 2014

    @dobkeratops

    nice, I have the same exact macro myself, except i add "{}:{}", file!(),line!(), ... and display the expressions eg "blah.rs:120 foo=... bar=... " etc. really handy ,as one can just click in the debug output and jump to a source location in some editors.

  8. reem commented on Jun 10, 2014

    @reem
    Contributor

    I was inspired by this issue to make a tiny library providing just such a macro that will also insert the file and line name, along with the expressions you are evaluating next to their results. Available here.

    Example:

    let a = 7;
    let b = 4;
    debug!(a, b, a + b);
    // => file.rs - 3: a = 7, b = 4, a + b = 11
  9. huonw commented on Jun 10, 2014

    @huonw
    Contributor

    @reem that is pretty cool. I would be somewhat interested in seeing that in libdebug (although it would need a different name, to avoid conflicting with liblog's debug), I'm not sure if others agree.

  10. reem commented on Jun 10, 2014

    @reem
    Contributor

    How about inspect!, or perhaps dump!? I personally like inspect! a bit more, just because it sounds a bit more professional :).

  11. seanmonstar commented on Jun 10, 2014

    @seanmonstar
    Contributor

    tiny precedence: util.inspect from nodejs, though it also colorizes and pretty prints json

  12. reem commented on Jun 11, 2014

    @reem
    Contributor

    I'd be willing to make a PR if that's the right thing to do in this situation?

  13. 6 remaining items

  14. sfackler commented on Sep 19, 2014

    @sfackler
    Member

    @thestinger "memory unsafe", not safe, I'd assume :)

  15. thestinger commented on Sep 19, 2014

    @thestinger
    Contributor

    @sfackler: Yeah, here's one example I didn't fix when I was working on this before: #9869

    I no longer have any interest in fixing the dozen remaining memory safety holes and dealing with the other breakage... and apparently no one else does, since it hasn't really been touched since then.

  16. SimonSapin commented on Sep 19, 2014

    @SimonSapin
    ContributorAuthor

    Given the direction {:?} is going, if I were to write an RFC for this I’d now propose generating {} instead. But I suspect that RFC would be postponed for the same reason as rust-lang/rfcs#163 was, so I won’t bother writing it just yet. If anyone else wants to, though, feel free.

  17. reem commented on Sep 19, 2014

    @reem
    Contributor

    I recently changed rust-inspect to use {} too.

  18. ftxqxd commented on Sep 19, 2014

    @ftxqxd
    Contributor

    Perhaps println!(), format!(), debug!() &c. could simply be extended to allow eliding the format string, making println!(foo, bar) equivalent to println!("{} {}", foo, bar). This has the slight disadvantage of silencing the error for println!(foo, bar) where foo is a string literal intended as a dynamic format string, and instead creating a bug at runtime. It would also be backwards-compatible, although still probably require an RFC.

  19. MatejLach commented on Sep 19, 2014

    @MatejLach
    Contributor

    +1 for making println!(foo, bar) equivalent to println!("{} {}", foo, bar) - would make things a lot less painful.

  20. SimonSapin commented on Sep 19, 2014

    @SimonSapin
    ContributorAuthor

    Yes, that sounds more likely to be accepted. Anyone wants to write up an RFC?

  21. seanmonstar commented on Sep 19, 2014

    @seanmonstar
    Contributor

    I submitted a PR doing that earlier in the year, it was rejected:
    #12384

  22. MatejLach commented on Sep 19, 2014

    @MatejLach
    Contributor

    @seanmonstar Yes, this was requested a couple of times already, but for some reason it keeps getting rejected by the core team.
    Maybe posting on Reddit and thus generating a wider debate on this would help?
    @alexcrichton Has you opinion changed on this in any way?
    Splitting this into a separate macro would defeat the purpose of this, I think.

  23. SimonSapin commented on Dec 10, 2014

    @SimonSapin
    ContributorAuthor

    I’ve renamed this macro show!, changed it to use {} (now that {:?} doesn’t exist anymore), and uploaded it to crates.io:

    https://crates.io/crates/show
    https://github.com/SimonSapin/rust-std-candidates#the-show-debugging-macro

  24. ivan commented on Feb 18, 2016

    @ivan
    Contributor

    I've published a crate called dump that extends the above #12015 (comment) to also print the type for each variable.

    (Update: If anyone uses it, I am looking for someone to adopt the repo and crate, please email me.)

  25. codyps commented on Oct 14, 2020

    @codyps
    Contributor

    For those googling: dbg!() in the standard library is probably what you want

  26. added a commit that references this issue on Jul 25, 2022
  27. added a commit that references this issue on Jan 11, 2024
    e73bb00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-syntaxextArea: Syntax extensions

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions