Hey all. Curious as to which of these two styles you would use. I'm working on a little clone of the wc
utility, and it has a number of options. There are two basic strategies: I can write the program like:
- Option handling
- Do the work
- print the results
Or, I can do
- do the work
- print the results based on option handling.
Style 1 looks like this:
let mut print_lines = false;
let mut print_words = false;
let mut print_bytes = false;
let mut print_chars = false;
let mut print_max_line_length = false;
let mut opts = Options::new();
opts.optflag("l", "lines", "print the newline counts");
opts.optflag("w", "words", "print the word counts");
opts.optflag("c", "bytes", "print the byte counts");
opts.optflag("m", "chars", "print the character counts");
opts.optflag("L", "max-line-length", "print the length of the longest line");
opts.optflag("h", "help", "display this help and exit");
opts.optflag("v", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => { m }
Err(f) => { panic!(f.to_string()) }
};
if matches.opt_present("l") {
print_lines = true;
}
if matches.opt_present("w") {
print_words = true;
}
if matches.opt_present("c") {
print_bytes = true;
}
if matches.opt_present("m") {
print_chars = true;
}
if matches.opt_present("L") {
print_max_line_length = true;
}
if matches.opt_present("h") {
print_usage(&program, opts);
return;
// do work
if print_lines {
print!("{}", lines);
}
if print_words {
print!("{}", words)
}
if print_bytes {
print!("{}", bytes)
}
if print_chars {
print!("{}", chars)
}
if print_max_line_length {
print!("{}", max_line_length)
}
println!(" {}", filename);
But I am always skeptical of ifs that just set booleans. I'm considering moving this to
let mut opts = Options::new();
opts.optflag("l", "lines", "print the newline counts");
opts.optflag("w", "words", "print the word counts");
opts.optflag("c", "bytes", "print the byte counts");
opts.optflag("m", "chars", "print the character counts");
opts.optflag("L", "max-line-length", "print the length of the longest line");
opts.optflag("h", "help", "display this help and exit");
opts.optflag("v", "version", "output version information and exit");
let matches = match opts.parse(&args[1..]) {
Ok(m) => { m }
Err(f) => { panic!(f.to_string()) }
};
// do work
if matches.opt_present("l") {
print!("{}", lines);
}
if matches.opt_present("w") {
print!("{}", words)
}
if matches.opt_present("c") {
print!("{}", bytes)
}
if matches.opt_present("m") {
print!("{}", chars)
}
if matches.opt_present("L") {
print!("{}", max_line_length)
}
println!(" {}", filename);
which seems like the code is cleaner, but the steps are a bit more intertwined. What do you think? Here's the full thing, original:
https://github.com/steveklabnik/rwc/blob/a119ad90c7fc4b19e0c44d22aa61ae7dfe99e7e1/src/main.rs
and new:
https://github.com/steveklabnik/rwc/blob/2a87bd17929ec6ff8301e8997d9c80c40426a387/src/main.rs