On 04/02/2009, Jakob Westhoff <ja...@westhoffswelt.de> wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > > Frederik Holljen wrote: > >>> Design goals ============ > >>> > >>> The workflow of a creating a SystemProcess object applying > >>> certain arguments as well as options to it and finally spawning > >>> the process should be intuitive as possible. The best way to > >>> achieve such an intuitive API would be to design it having the > >>> fluent interface pattern in mind. The used interface should look > >>> something like this:: > >>> > >>> new ezcSystemProcess( 'echo' )->argument( 'foo' )->execute(); > >> > >> Method chaining can not be done with "new classname", so it has to > >> be: > >> > >> $p = new ezcSystemProcess( 'echo' ); $p->argument( 'foo' > >> )->execute(); > > > > I don't see why the fluent interface pattern makes this more > > intuitive. I'd say it makes it less intuitive as a command is really > > not complicated at all and the fluent interface pattern is to make a > > complicated API more intuitive to use. > > > > Consider: cmd = array( 'program_name', 'arg1', 'arg2', 'arg3', > > 'arg4', 'arg5', 'arg6', 'arg7' ) pOpbject = > > ezcSystemProcess::execute( cmd ) > > > > vs $p = new ezcSystemProcess( 'program_name' ); $p->argument( 'arg1' > > )->argument( 'arg2' )->argument( 'arg3' )->argument( 'arg4' > > )->argument( 'arg5' )->argument( 'arg6' )->argument( 'arg7' > > )->execute(); > > > > Which one is easier to read and less hassle to write? Another > > advantage of the top one is that you can easily alter one parameter > > and then run the command again. > > > I agree with you, that in the case presented above the array seems to be > more readable. But as soon as arguments tend to get a little bit longer > or contain variables in my opinion the fluent interface provides much > more readability, especially with proper formatting. > > In a lot of use cases you will also want to define some other aspects of > the execution like the file descriptor redirects, pipes, the working > directory, custom file descriptors or a custom environment. > > By providing the described fluent interface all this could be done using > the same kind of api, which seems to be more consistent and readable to > me. Let me give a simple example: > > $p = new ezcSystemProcess( 'foobar' ); > $p->workingDirectory( 'my/directory' ) > ->environment( 'MY_ENVIRONMENT_VARIABLE', '42' ) > ->environment( 'MY_OTHER_ENVIRONMENT_VARIABLE', '23' ) > ->redirect( ezcSystemProcess::STDERR, ezcSystemProcess::STDOUT ) > ->redirect( ezcSystemProcess::STDOUT, '/tmp/some/file') > ->argument( '--first-option' ) > ->argument( '--second-option-with-a-value' ) > ->argument( $someValue ) > ->pipe( $anotherSystemProcess ) > ->execute(); To me this reads like the environment has a redirect and that the argument has a pipe etc. How is the above an improvement over the classical interface: $cmd = array( 'foobar', '--first-option', '-second-option-with-a-value', $someValue ); $p = new ezcSystemProcess(); $p->workingDirectory = 'my/directory': $p->addEnvironment( 'MY_ENVIRONMENT_VARIABLE', '42' ) $p->addEnvironment( 'MY_OTHER_ENVIRONMENT_VARIABLE', '23' ) $p->addRedirect( ezcSystemProcess::STDERR, ezcSystemProcess::STDOUT ) $p->addRedirect( ezcSystemProcess::STDOUT, '/tmp/some/file') $p->addPipe( $anotherSystemProcess ) $p->execute( $cmd );
I think the latter more clearly describes the relation between the options and the process. > I am not perfectly sure about the environment part. Maybe it makes sense > to take an array with key/value pairs here, as setting the environment > might be quite a hassle otherwise. > The manipulations of single arguments later on in the process is > possible as well using the described way. The object could just be > cloned at the proper position of the creation process and adjusted with > the needed argument calls: > > $p1 = new ezcSystemProcess( 'foobar' ); > $p1->workingDirectory( 'my/directory' ) > ->argument( $someInputFile ) > ->argument( '--some-option' ); > > $p2 = clone $p1; > > $p1->argument( $firstOutputFile ) > ->execute(); > $p2->argument( $secondOutputFile ) > ->execute(); What if you want to change the first and the fourth argument? What do you do if you try to clone a process that is already executing? Kore: I didn't quite catch your comment. Care to explain in more detail? Cheers, Frederik -- Components mailing list Components@lists.ez.no http://lists.ez.no/mailman/listinfo/components