4 ms·
That you need a "framework" to build simple CLI tools does not seem to speak too well of the language. I know nothing about rust, but isn't there a simple faci
by enriquto 6y ago
That you need a "framework" to build simple CLI tools does not seem to speak too well of the language. I know nothing about rust, but isn't there a simple facility for using argc, argv, and the like?
- DougBTX 6y agoYes, that's std::env::args[0], however a higher level wrapper (I prefer structopt[1]) makes it trivial to produce nice usage output etc. [0] https://doc.rust-lang.org/std/env/fn.args.html https://doc.rust-lang.org/std/env/fn.args.html [1] https://github.com/TeXitoi/structopt https://github.com/TeXitoi/structopt
- ibraheemdev 6y agoYou do not "need a framework" to build simple CLI tools in Rust. Most people use a command line argument parser, the most popular being clap [0]. Or you can just use std::env directly. 0: https://github.com/clap-rs/clap https://github.com/clap-rs/clap
- masklinn 6y agoOr you can use getopts if that's your thing (it's also a library so limited gain over clap/structop, probably smaller & faster to compile though) e.g. that's what Brian Cantrill does[0] because they're an old fogey[1] :D [0] https://github.com/joyent/statemap/blob/rust/src/main.rs#L95 https://github.com/joyent/statemap/blob/rust/src/main.rs#L95 [1] https://github.com/joyent/statemap/pull/41 https://github.com/joyent/statemap/pull/41
- bcantrill 6y agoNot only had I entirely forgotten about that, I now use structopt for everything -- so at least this old dog can still learn new tricks? ;)
- nicoburns 6y agoYou definitely don't need a framework. This seems to be aimed at extras like fancy logging, config file management, and CI setup.
- kibwen 6y agoOf course, std::env::args: https://doc.rust-lang.org/std/env/fn.args.html https://doc.rust-lang.org/std/env/fn.args.html What clap gives you is something more like Python's argparse, which offers things like convenient parsing, automatically generated manpages and error/usage messages, etc.
- vultour 6y agoMost languages have terrible CLI parsing support, I have yet to find something built in that matches Python’s argparse module. Hell, even “modern” languages like go suffer from this.
- ibraheemdev 6y agoPython’s success is at least partially due to its “batteries included” methodology, but many of its standard modules didn’t get any support because external solutions just turned out to be better. Rust maintains a small but high quality standard library in part to avoid the problems that Python's standard library fell into. Things like cli parsers can be downloaded easily using cargo's amazing tooling. We get packages like structopt for example, which provides a custom derive parsing command line arguments: #[derive(StructOpt)] struct Opt { #[structopt(short, long)] debug: bool, #[structopt(short = "c", long)] nb_cars: Option<i32>, #[structopt(short, long)] level: Vec<String>, }
- masklinn 6y agoIMO structopt is way superior to argparse (which is itself not very good, it works to avoid a dependency but if I already have dependencies I'd rather use click).
- Ciantic 6y agoIn this case the framework means set of dependencies. If you want to parse short-opts, long-opts etc. you need dependencies in most languages. Python is an exception, because of batteries included approach. With Rust you will soon see that most applications require some sort of dependency like serde for serialization, etc.
- Waterluvian 6y agoAs long as you're not doing any complex argument handling, it's dead simple: https://github.com/ablakey/gameboy/blob/master/src/main.rs#L9 https://github.com/ablakey/gameboy/blob/master/src/main.rs#L... (I'm sure people will shout that this isn't the right way to parse optional flags)
- kibwen 6y ago> (I'm sure people will shout that this isn't the right way to parse optional flags) Since that sounds like a challenge, just wanted to make sure that people are aware of Iterator::nth (https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.nth https://doc.rust-lang.org/std/iter/trait.Iterator.html#metho...), which means you can entirely replace lines 8 and 9 with `let cartridge_path = env::args().nth(1);` :) In combination with Iterator::any to replace line 10, you can avoid a whopping five whole heap allocations this way!! :P
- Waterluvian 6y agoOoooh thanks for sharing! I am a beginner to Rust (this emulator being my second project). I was not aware of that. I feel like when I'm done I need to find a bit of cash and get a veteran to code review the whole thing. I'm learning a ton by suffering through it myself. But also probably missing a lot of great shortcuts and tips. I assume the "five heap allocations" is kinda tongue in cheek? My understanding is that while it is good to avoid heap allocations, given this is a called-once piece of code, it's not really a big deal?
- kibwen 6y ago> I assume the "five heap allocations" is kinda tongue in cheek? My understanding is that while it is good to avoid heap allocations, given this is a called-once piece of code, it's not really a big deal? Indeed. :) I can't envision a circumstance where avoiding exactly five small allocations outside of any loop would be observable in either time or memory usage. As a Rust programmer it simply provides a warm and fuzzy feeling to avoid allocations in places where it not only doesn't obscure the code, but actually makes it shorter. At best, this could be a small step towards running your code on embedded hardware (which isn't unreasonable for an emulator like this), but only if you were to also eliminate all other allocations within your program.