Why D Needs Attributes (Was: Command-line arguments)
Nick Sabalausky
a at a.a
Fri Jul 4 01:19:39 PDT 2008
"superdan" <super at dan.org> wrote in message
news:g4kit6$nuq$1 at digitalmars.com...
> Nick Sabalausky Wrote:
>
>> "Nick Sabalausky" <a at a.a> wrote in message
>> news:g4k93l$1mh$1 at digitalmars.com...
>> > "Jarrett Billingsley" <kb3ctd2 at yahoo.com> wrote in message
>> > news:g4ju5s$2dh0$1 at digitalmars.com...
>> >> "Matt" <no-one at none.nowhere.com> wrote in message
>> >> news:g4jqum$269v$1 at digitalmars.com...
>> >>> Is there an established library in D for handling command-line
>> >>> arguments?
>> >>>
>> >>> In particular:
>> >>> - handling differences between Windows and UNIX shells (i.e. wildcard
>> >>> expansion)
>> >>> - handling equivalent options such as "-n 10" === --count=10
>> >>> - handling combination of multiple flags, e.g. "-lcf" == "-l -f -c"
>> >>>
>> >>> Thanks
>> >>>
>> >>> Matt
>> >>
>> >> I don't believe there is an argument parser in either Phobos 1 or
>> >> Phobos
>> >> 2.
>> >> However, there is one in Tango.
>> >>
>> >
>> > Command-line parsing is one of the big reasons I really wish D had
>> > C#/Java
>> > style attributes. I came across this one particular C# command-line
>> > parser
>> > (written by a Peter Hallam) a few years ago and absolutely fell in love
>> > with it, and by extention, attributes. (I'd link to it, but it was on
>> > GotDotNet, which MS replaced with something else and didn't move this
>> > particular program over. So I'm attaching the lastest version I have
>> > (only
>> > about 11k), even though there are newer versions...somewhere.)
>> >
>> > Just check out how awesomely simple it makes this sample case:
>> >
>> > BEGIN CODE
>> > class WCArguments
>> > {
>> > public bool lines;
>> > public bool words;
>> > public bool chars;
>> >
>> > [Utilities.DefaultCommandLineArgument(Utilities.CommandLineArgumentType.MultipleUnique)]
>> > public string[] files;
>> >
>> >
>> > [Utilities.CommandLineArgument(Utilities.CommandLineArgumentType.AtMostOnce,
>> > ShortName = "num")]
>> > public int number;
>> > public string[] junk;
>> > }
>> >
>> > class WC
>> > {
>> > static void Main(string[] args)
>> > {
>> > WCArguments parsedArgs = new WCArguments();
>> > if (!Utilities.Utility.ParseCommandLineArguments(args,
>> > parsedArgs))
>> > {
>> > // error encountered in arguments. Display usage message
>> >
>> > System.Console.Write(Utilities.Utility.CommandLineArgumentsUsage(typeof(WCArguments)));
>> > }
>> > else
>> > {
>> > // insert application code here
>> > }
>> > }
>> > }
>> > END CODE
>> >
>> > The WCArguments class is itself the very definition of the program's
>> > command-line arguments. And attributes can be used to specify things
>> > like
>> > "DefaultCommandLineArgument", "MultipleUnique", "AtMostOnce",
>> > "ShortName",
>> > "Required", etc. Later versions include automatically-generated help
>> > screens. And the command-line syntax is the same
>> > ultra-clean-consistent-and-unambiguous commandline syntax that MS's
>> > command-line .NET tools use.
>> >
>> > D2 could probably come close to this with its compile-time reflection,
>> > but
>> > I don't think there'd be a comparably simple way to specify the things
>> > that this uses attributes for.
>> >
>>
>> I just took a look at Phobos2's getopt. It's impressively code to this in
>> functionality. But I still think this is much cleaner and more DRY
>> ("drier"?)
>>
>>
>
> in the words of the annoying chick in friends: oh....... my....... god!
> how could that dung be better than this?
>
> void main(string[] args)
> {
> bool lines = true, words = true, chars = true;
> string[] files;
> int number;
>
> getopt(args,
> "lines", &lines,
> "words", &words,
> "lines", &lines,
> "files", &files,
> "num", &number);
> ........
> }
>
> this does everything that does /without/ adding a new class and redundant
> shit in square brackets. the fact that there could be multiple files is
> inferred from the type string[]. no new class, no attributes, no mess.
> shit man that c# stuff really blows. awesomely blows if you wish. how can
> anyone like that shit. to say nothing about the no-good generated help
> string that always is too short and uninformative to help shit.
>
> p.s. look! i wrote an entire post and no fuck! fuck me but this is weird.
> oops i fucked up again. :)
The getopt version forces you to list each variable three times. Once for
the variable itself, once more to tell getopt what it's called, and a third
time to tell getopt where it is. That's highly redundant. They're only
listed once for the C# version. (The getopt version could probably be
changed to extract the name from the variable using templates and traits
though, and it could probably eliminate the rest of that redundancy by
sticking the vars into a class or stuct, but then it would lose the ability
to let you specify options for each var. Attributes would bring that ability
back without creating reduncancy).
Regarding the C# version:
- Sticking the variable declarations inside a class is trivial.
- All of the stuff in square brackets (attributes) are optional.
(If you do specify any attributes, then the AttributeType is required,
however I was able to remove that restriction in about two minutes by adding
two trivial constructors.)
- You can specify a custom help string for each element.
- The fact that there could be multiple files *IS* inferred by using an
array of strings. (At least if you don't use any attributes, that is. But
that can be fixed fairly easily too.)
If anyone's interested, I found a link:
http://www.codeplex.com/CommandLineArguments
More information about the Digitalmars-d
mailing list