0

I'm trying to write some of my own debugging macros, and was looking at source code for rusts build in dbg!:

macro_rules! dbg {
    () => {
        $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!());
    };
    ($val:expr $(,)?) => {
        // Use of `match` here is intentional because it affects the lifetimes
        // of temporaries - https://stackoverflow.com/a/48732525/1063961
        match $val {
            tmp => {
                $crate::eprintln!("[{}:{}] {} = {:#?}",
                    $crate::file!(), $crate::line!(), $crate::stringify!($val), &tmp);
                tmp
            }
        }
    };
    ($($val:expr),+ $(,)?) => {
        ($($crate::dbg!($val)),+,)
    };
}

Several things confuse me about this code:

  1. What is $ operator peppered throughout this code doing?
  2. What the plane language equivalent of ($val:expr $(,)?)? I don't understand what the , is and why it is there.
  3. Why does the macro definition start with () => {$crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!());};?
ANimator120
  • 2,556
  • 1
  • 20
  • 52
  • 1
    3. Using it as dbg!() without any parameters will output current position in the source file. – Ivan C Jan 28 '21 at 23:06

1 Answers1

5

What is $ operator peppered throughout this code doing?

macro_rules! has distinct syntax on top of normal Rust. The $s are used to indicate metavariables (like $ident) and repetitions (like $(...)). You should probably do some preliminary research on what a Rust macro is:


What the plane language equivalent of ($val:expr $(,)?)? I don't understand what the , is and why it is there.

The $val:expr defines a pattern that will match a single expression. The $(,)? matches a , that may exist zero or one times. Effectively makes it so that the dbg! will allow optional trailing commas (so as to mimic most of Rust). You'll see this reflected in the other pattern $($val:expr),+ $(,)?.


Why does the macro definition start with () => {$crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!());};?

This macro is designed to be called with any number of arguments, including zero. The () => { ... }; pattern allows for dbg!() to be valid. The effect of calling dbg! with no arguments is to just log the file and line number.

kmdreko
  • 42,554
  • 6
  • 57
  • 106