Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Ticket #748: Arguments_Docs.txt

File Arguments_Docs.txt, 6.5 kB (added by darrylb, 9 months ago)

Some preliminary tutorial / docs

Line 
1 --Tango Arguments - Flexible argument string parsing.
2
3 -Introduction
4
5 Arguments is a module for parsing argument strings, such as command line arguments passed to main(). It is an extrememly flexible module, able to accomodate a wide variety of desired parsing behavior. Arguments follows a declarative paradigm, requiring the programmer to tell it some basic information about the arguments and any possible parameters. However, it also will parse a given string using a default set of actions that covers most basic use cases.
6
7 Here's the most basic example of using Arguments:
8
9 void main(char[][] cmdl)
10 {
11     auto args = new Arguments(cmdl[1..$]);
12 }
13
14 And that's it. If the program were called with, say, a command line like:
15
16 myProgram -a=read --files text1.txt text2.txt
17
18 Then you would be able to perform the following operations:
19
20 if ("a" in args)
21     char[] action = args["a"][0];
22     ... do something cool
23
24 if ("files" in args)
25     char[][] processFiles = args["files"];
26
27 And so on. This is the basic operation mode of Arguments, and it's designed to get you up and running quickly with a minimum of fuss. However, there is a lot more going on under the hood than just this, if you tell Arguments a little bit of information beforehand, it becomes quite powerful in it's ability to decipher argument strings into something coherant for your particular program.
28
29
30 Here's a slightly more complex example:
31
32 void main(char[][] cmdl)
33 {
34     auto args = new Arguments;
35     args.define("a").parameter;
36     args.define("b");
37     args.parse(cmdl[1..$]);
38 }
39
40 Here, we've told Arguments a little bit of what we're expecting, by using the .define method. This method is what allows you to set up argument definitions, and there are quite a variety of chaining methods that you can use along with a define. We'll get into them all a little later on. For now, let's accept that .define("a").parameter tells us that the argument "a" expects to get a parameter, and that .define("b") tells us that while we can expect to see a "b", it doesn't take any parameters.
41
42 With that information, if the program were called with a command line like:
43
44 myProgram -b -a hello
45
46 Then we can know that we now have '"b" in args' and that 'args["a"] contains "hello"', as one would reasonably expect.
47
48 But wait, you say. Isn't that the same thing that would have happened if I hadn't made any definitions at all? Why did I waste my time calling .define?
49
50 You are indeed astute, young grasshopper. Your efforts in calling .define were not in vain, however, and here's why.
51
52 Assume that instead of the above command line, you were instead called like this:
53
54 myProgram -ab hello
55
56 Which you want to have parsed the same way as the previous command line. Well, without having defined your arguments beforehand, Arguments would have parsed that as:
57
58 "a" in args
59 "b" in args
60 args["b"][0] = "hello"
61
62 Which isn't quite right. However, we did tell Arguments about how we wanted our command line parsed beforehand, and because it already knows that "a" takes a parameter but that "b" does not, it will have parsed that line the same as the previous. In other words, because we gave it a little bit of information beforehand, the command lines:
63
64 myProgram -b -a hello
65 myProgram -ab hello
66
67 Will not appear any differently to our program, transparently to us using Arguments, those two command lines are the same. This is some of the power and flexibility of Arguments. But that just barely scratches the surface.
68
69
70 -Background
71
72 Arguments was designed to be as flexible as possible, and to support a wide variety of command-line paradigms while still maintaining a declarative nature, as opposed to format-string style parsers that are inheriently less flexible with regards to positioning, and also require the user to have some knowledge of some arcane syntax. It does, however, follow a few conventions which the user should be familiar with.
73
74 -Terminology
75
76 argument
77     an argument is one particular item that will be queryable post-parse. Given a command string '-a -b --cde', all of "a", "b", and "cde" are arguments. There are also two distinct types of arguments, long and short.
78     short argument
79         a short argument is a single character, prefixed by the short-argument prefix (by default, this is "-"). Short arguments may be collected together, for example, "-a -b" and "-ab" are identical.
80     long argument
81         a long argument is a series of characters, prefixed by the long-argument prefix (by default, this is "--"). Long arguments may not be collected together.
82
83 parameter
84     a parameter is an attribute of one particular argument. There may be multiple parameters for any given argument. Given a command string '-a 1' and assuming a basic parse, "a" is an argument, and "1" is a parameter to "a".
85     standard parameter
86         parameters can also directly follow arguments if they are delimited by a delimiter (by default, they are ":" and "="). So, '-a 1', '-a:1', and '-a=1' are all identical.
87     implicit parameters
88         a parameter that has no associated argument. This can happen if all arguments are defined not to take any parameters, or if no arguments were given at all. implicit arguments are availble after parse in args[null].
89
90 -The function of command line arguments
91
92 Command line arguments typically provide information that customizes the program execution. These given arguments may be required or optional, the Arguments module itself does not presume to tell you how your program should function, it's up to you to tell it how you want it to work.
93
94
95 --Reference
96
97 -Overview
98
99 First, you import the Arguments module.
100
101 import tango.whatever.Arguments;
102
103 The, you create a new Arguments instance:
104
105 auto args = new Arguments;
106
107 If you pass the Arguments constructor the string you'd like it to parse, you can be done right here.
108
109 auto args = new Arguments(cmdl[1..$]);
110
111 Otherwise, after creating your new arguments, you will then set up any needed configuration:
112
113 args.prefixLong ~= ["%%"];
114 args.define("x").required.parameters(0,1);
115
116 And then finally, call parse:
117
118 args.parse(cmdl[1..$]);
119
120 After which, can you then access the information parsed from your command line string.
121
122 if ("x" in args) {}
123 char[] myVal = (args["value"][0]);
124 etc..
125
126 -args.prefixShort
127
128 -args.prefixLong
129
130 -args.delimiters
131
132 -args.reset
133
134 -args.remove
135
136 -args.count
137
138 -args.define
139
140 --define.parameters
141 --define.defaults
142 --define.delimiters
143 --define.required
144 --define.aliases
145 --define.conflicts
146 --define.requires
147 --define.callback
148 --define.validation
149
150 -how to generate help text
151
152 -some sample use cases
153     long arguments with single hyphen
154         myProg -pf -> (args["pf")
155
156     different prefixes
157         myProg +f +rgb
158         myProg /file
159
160     no delimiters
161         myProg -ffile1.txt