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

Process use cases?

Posted: 11/20/08 15:30:19

I'm adding yet another option to tango.sys.Process that allows for specifying redirection of stdout/stderr/stdin. This allows one to only redirect one or two of those handles, and leave the rest to point to the current stdout/err/in.

What I'm realizing is that as I add new orthogonal features to Process, the constructors are multiplying. In addition, the execute function pretty much duplicates all the same arguments as the constructor.

What I'm wondering is if people actually use the arguments to execute, or if they just use the constructor and properties to set up the process, and then call execute with no arguments? It would make my job much easier if there was only one execute function.

Or, alternatively, would it make sense to allow uncommon options (such as specifying redirection) to only be settable through properties, and then use call chaining to do it all in one line, without having 2n different functions?

auto p = new Process("ls");
p.setRedirection(Redirect.Stdout).execute();

Thoughts? Suggestions?

Author Message

Posted: 11/20/08 19:16:40

I think the property approach may be the best solution if there are yet more properties that may be needed in the future.

Posted: 11/22/08 01:32:43

Now there are three ways of setting the command line: the constructor, properties, and execute. I wouldn't mind if execute() was changed into a single function with no parameters. Three's a crowd and all that. The argument against it it that in some cases it will take more lines of code if you're reusing Process instances, which doesn't seem like an important use case. I don't even know if they are reusable.

I actually use execute(char[] command, char[][char[]] env) in my code, but I'll be happy to use the constructor instead. All in the name of simplifying the Process class. :)

Posted: 11/22/08 03:56:36 -- Modified: 11/22/08 03:57:07 by
schveiguy

Torhu, My preferred option would be to only allow setting of uncommon properties, such as the proposed redirection flags, through the property interface (and maybe one constructor version which sets everything). Otherwise, I have to think of ways to make constructors that have the right combinations of properties that people want.

Does this sound usable to you? You would still have most of the constructors that are there now (including the one you mentioned), but only ones that are deemed to be very common. And execute would be a single no-argument function.

I'm not sure if you can reuse a process object, but it feels wrong to me.

Posted: 11/22/08 21:46:31

Sounds good to me.

As for redirection...

p.setRedirection(Redirect.Stdout).execute();

This looks more D to me:

p.redirection = Process.Stdout;  // only stdout
p.execute();
...
p.redirection = Process.Stdout | Process.Stdin;  // only stdout and stdin
p.execute();
...
p.redirection = p.redirection | Process.StderrToStdout // useful?
p.execute();
...
p.redirection = 0;  // disable redirection
p.execute();

'redirection' would be a regular getter/setter pair, default value (Process.Stdout | Process.Stdin | Process.Stderr).

Posted: 11/24/08 23:26:29

Yes, Process.StderrToStdout and friends are reasonable additional flags to allow. Since you can't have opened the pipes before calling execute, it's not possible to pass in file handles for your requested redirection.

Eventually, there should probably be a way to pass in a file handle (to redirect to file, or socket, or whatever), which would be a separate method.

I'll implement with your ideas for redirection in mind, thanks!

And regarding the property notation, I feel like this is a reasonable model:

class C
{
// define property prop
int prop();
int prop(int newval); // returns newval after setting, so it can be used like a normal rvalue.
C setProp(int newval); // returns this for chaining

// define property plop
int plop();
int plop(int newval);
C setPlop(int newval);

}

// usage:

auto c = new C;
c.prop = c.plop = 5; // use normal property syntax as rvalues
c.setPlop(5).setProp(6).method(); // use chaining

I'll implement this way and see who complains ;)

Posted: 11/26/08 21:48:26

My take on this would be that having something both as a property and setter that returns this to allow for chaining calls is a net loss. Even if one way is slightly better than the other in a given context, the difference is so small that it's not worth it. If you make the programmer spend brain power choosing between two ways of doing the same thing, I feel there should be a real gain to it. In choosing which one to include, consistency with the rest of Tango is probably the most important consideration.

Maybe the args, env, and programName properties are not needed? They are all essential constructor arguments, and the user can easily keep them around himself if he needs them again. I had a look at the Popen class in Python's subprocess module, which has none of those properties available. toString is nice to have, though, and D coders will expect it to be present.

Consider that a complaint. ;)