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