Why D Needs Attributes (Was: Command-line arguments)

superdan super at dan.org
Fri Jul 4 07:37:45 PDT 2008


Nick Sabalausky Wrote:

> "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.

narp. getopt is better for 2 reasons. first, if i want to have an option with a dash in it, with getopt you say;

bool showControlChars;
getopt(args, "show-control-chars", &showControlChars);

i and you and anyone who's used getopt once knows how to do that. but i have no idea how to do that in c#. there may be some shitty attribute to do so but i have to go check the manual. who wins?

second, yarp i do define the var and then specify it in the getopt thing. but that's a good thing, gives me freedom. i can put it locally, or at module level, or in another object. but in c# it's always a member of a new type. shit. i have to define a freakin' *type*. that's useless baggage. why do i have to define a type to parse my command line shit. thanks but i'll use getopt. 

>  (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).

run ls --help. you'll see there are 18 options with dashes in'em and 23 without. that's like 40/60. 

but then maybe some-option-x could be converted automatically to someOptionX by a template. heh we have an enhancement idea right there.

> Regarding the C# version:
> - Sticking the variable declarations inside a class is trivial.

yarp but i have to have a class in the first place.

> - 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.)

two minutes for command line shit is two minutes too many. that's the problem. command line is easy shit. should be a !brainer. everybody doing command line shit asks me to waste time with their crappy api. getopt in phobos is the first ever to ask me to be done with it in seconds and move on. i think it makes it look so simple people don't see what a work of art it is.

> - You can specify a custom help string for each element.

guess this could be improved in getopt:

uint shits;
getopt(args,
    "shits number of shits given for this run", &shits);

so then the space separates the option from the help string.

> - 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.)

hum. so then why would the attributes be needed in the first place.

> If anyone's interested, I found a link:
> http://www.codeplex.com/CommandLineArguments

sorry won't read. :)




More information about the Digitalmars-d mailing list