I don’t own this book so I cannot comment on the code, but here are a few tricks I use to debug chained methods and see the intermediate values. I’m using the IntelliJ plugin.
To just see the types at different point, the same techniques can be used - check values in a map, or split the chained method into several intermediate variables.
To take a dummy example:
let values = vec!["one", "two", "three"];
let values_str = values.iter()
.enumerate()
.map(|(i,s)| {
format!("{}: {}", i + 1, s) // <== breakpoint here
})
.collect::<Vec<_>>()
.join(", "); // <== breakpoint here
println!("Result: {}", values_str);
It’s possible to place a breakpoint on the map closure. Make sure to use a block with ‘{ … }’ and that the code is not on the same line. Otherwise, values are not visible:
.map(|(i,s)| { format!("{}: {}", i + 1, s) }) // <== I cannot see anything
It’s also possible to put breakpoints on the lines after, but on the lines before it’s a bit tricky because it’s an iteration and there is no closure to expose any value. The debugger will stop but will not show anything. Sometimes you may be able to step into the function and catch something from there, but it’s tedious.
One way to look is to insert a dummy identity map. For example if I want to catch the values before the enumerate:
let values_str = values.iter()
.map(|x| {
x // <== breakpoint here
})
.enumerate()
.map(|(i,s)| { format!("{}: {}", i + 1, s) })
.collect::<Vec<_>>()
.join(", ");
You can even put a println!()
, that’s usually easier than looking at the values in the debugger.
Another way is to simply split the calls and store the intermediate result in temporary variables. Note the clone()
to avoid losing ownership on the intermediate data:
let values = vec!["one", "two", "three"];
let values_str_1 = values.iter()
.enumerate();
let debug = values_str_1.clone().collect::<Vec<_>>();
let values_str = values_str_1 // <== breakpoint
.map(|(i,s)| { format!("{}: {}", i + 1, s) })
.collect::<Vec<_>>()
.join(", ");
println!("Result: {}", values_str);
PS: I found out that with that plugin, you had disable the NatVis renderers if you examine the values in the LLDB view, otherwise you get a lot of warnings hindering the view: