In this lecture, we are going to learn how to debug an application with macros.
Macros are an advanced subject.
Unfortunately, we won't be able to dive into how macros are created.
There isn't enough time to review the code of a macro.
So instead, this lecture will be a light introduction to them.
Don't worry, it'll be enough to work with WebAssembly.
So what are macros?
First, we need to understand something called meta programming, which can be a trippy concept.
It's when a program can write a program.
Literally copying and pasting code is a classic developer move.
We all do it.
What if we could write our program that copies and paste code?
I'm oversimplifying it, but that's met our programming in a nutshell, bringing it back to rust.
A macro is a feature for writing code in our program.
Russ will copy and paste code defined in the macro, which is a form of meta programming.
It can be a difficult concept to wrap your head around.
Writing a macro is very difficult.
Luckily, it's not something we'll need to do as long as we know how to use them will be good to go.
Using a macro is very easy.
The syntax is similar to a function in our main function.
We are storing the sum of two numbers in a variable called fill.
Let's output the results onto the console.
Russ defines a macro for this specific action below the few variable.
Let's add a macro called Prince l'N in the letters L and are short for a line.
Almost immediately, you'll notice a strong similarity between calling a macro and calling a function.
We write the name of the macro, followed by a pair of parentheses.
The biggest difference between a macro and function is the exclamation mark character.
It'll always appear after the name.
This is how you can identify macros.
Another similar feature a macro share with functions, is arguments in between the parentheses.
We can pass on a value to print the terminal.
Let's try passing in a Hello World message.
Next, let's run our program with the cargo run commands.
The message gets output it as desired.
However, we get a warning from the compiler.
It's telling us the few variable is unused.
Let's replace the string with the few variable in the prince macro.
The compiler will throw an error.
It's very strict with the types of values we can pass on to macros and functions.
On the one hand, it's very convenient, but not in this case.
There are scenarios where we are going to need to debug values other than strings.
We might want to debug arrays, numbers or billions.
Luckily, the print line macro supports formatting.
We can inject values into a string.
Let's replace the few variable with a string inside the string.
We're going to add a pair of curly braces the Curly Braces Act as a placeholder before robust outputs
the string.
It'll replace the placeholder with the value of our choosing.
We can add a value as a second argument to the print line macro.
Let's try running the cargo run command in the terminal.
The variables value gets displayed.
Perfect.
We're able to debug our values by inspecting them in the terminal.
The print line macro is more flexible than you can imagine.
For example, what if we want to output multiple values?
The argument list is limitless inside the string.
Let's add another placeholder.
An error will be thrown by the compiler.
It's unable to find a value for the second placeholder.
Let's add a Boolean value as an argument to the macro.
Lastly, let's compile our code.
Russ was able to replace our values.
The order of placeholders will correlate to the order of arguments.
The first placeholder will be replaced with the second argument.
The second placeholder will be replaced with the third argument.
So on and so forth.
In some cases, we may want to reuse a value.
The print macro supports positional arguments.
I'm going to remove the Boolean value after removing it.
The compiler will throw the same error as before instead of adding a new value.
We can point to a specific argument by adding a number inside the placeholder.
The number is a position to a value in our argument list.
Positions are zero based.
Therefore, zero will point to our food variable.
Let's head zeros to both placeholders.
Next, let's compile our project.
Both placeholders are replaced with the number.
There's one less trick I want to show you and some examples you may see developers use a different placeholder.
The syntax is slightly different than a regular placeholder.
Let's reset the string to a regular placeholder.
Inside the curly braces, let's add a colon and question mark character.
This type of placeholder works for complex values.
Russ gives developers the flexibility of manipulating a value before it gets output it onto the terminal
for debugging purposes.
If a developer decides to do that, we will need to use this placeholder.
Let's try compiling the project.
We get the same output as before.
It's not apparent as to why we will use this placeholder.
I promise you, when we start working with complex values, this placeholder will come in handy.
We've talked a lot about macros.
They're similar to functions, functions and macros are written the same with the exception of the exclamation
mark symbol for macros.
They both have a list of arguments.
Conceptually, they can achieve similar goals.
We can outsource logic into both features.
So what are the differences?
Macros support the following features periodic arguments, pretty syntax and meta programming.
These topics are beyond the scope of this course.
I want to emphasize you don't need to know how to write macros for this course.
The macros shipped with rust will suffice for most cases as long as you know how to use them.
Everything will be smooth sailing.
Let's continue our journey in the next lecture.