Recently, I read a post about a useful command-line tool library called docopt, and it reminded me of my experience with Crystal’s OptionParser.
As you know, Crystal’s standard library OptionParser can create command-line tools with subcommands. I am using OptionParser to build a command-line tool with subcommands.
However, I am confused about the with_preserved_state
feature in the parser
method. This feature saves the parser’s state and resets it after parsing. This can be inconvenient when you want to perform an action after parsing all arguments. For example, if you want to show help for a subcommand:
dog paw --help
If you want to display the subcommand’s help message after parsing all arguments, you need to save the help message in a separate variable because the parser forgets it after execution.
on("-h", "--help", "Show this help") do
@action = Action::Help
end
@help_message = self.to_s
Similarly, the parser doesn’t remember which subcommand it parsed, so you also need to save that yourself. This might be fine.
Resetting the parser’s state is useful for testing. However, command-line tools usually parse arguments only once at runtime. So, situations where you need to parse options multiple times are rare. In such cases, it would be better to have an explicit clear
method.
Crystal is an object-oriented language, and it’s natural for classes to have state. parse
is a method of the OptionParser class, not a module function. So, it’s not intuitive that the method’s behavior is transparent unless you read the source code.
Maintaining backward compatibility is important. It would be helpful if the parse
method had an optional argument to choose whether to use with_preserved_state
.
These are my personal thoughts based on my use case with OptionParser. It might not apply to all users, but I wanted to share my concerns.
(Translation by ChatGPT)