-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Frederik Holljen wrote: > 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.
As far as I am concerned the fluent interface provides the way to create the command both ways. As you are not forced to use it, but have the chance to do so. Moreover it would be more consistent with the database abstraction component. >> 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? Thats a problem, which may be solved using the way I described in my other response to the idea of trying to reuse the database abstraction api. (Message-ID: <4989b633.6090...@westhoffswelt.de>) > > Kore: > I didn't quite catch your comment. Care to explain in more detail? > > Cheers, > Frederik best regards, Jakob - -- Jakob Westhoff (GPG 0xCBF7FC6A) http://westhoffswelt.de -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQEcBAEBAgAGBQJJibf6AAoJEE0XwzzL9/xqjsMH/14AZxQZFT+RhxaKxY6ehGem MIVwi5eiJLV27aDtl6BXon3fSBfrPb78Jq6ymlkdrbwIl9JdbLfE3c2o4crobvrp wJQtHHgQU7pl4vAl9XXCQ+dEwlos7BRtkZp+cKpEeXYMwCUT0UJxanOIKrG0Hp7M 2aKrZJQesTUIj9ANp04kISqOxhBJZdZM+cLK/JIjiN0ZYhdmTz1eNs++jq5SpvM9 KCOH8+1956/6JKwhobKLOUj+i2IZxnbTU0o7ZbPLv+t8lgyHrbk/3JjrXeJjKkv6 7OtyxlGlHzK0I+J1nOozGJK6RjBKu33Gi07R5T5rvN9nVxBAlNNCkAhlC/4BsGw= =Scnd -----END PGP SIGNATURE----- -- Components mailing list Components@lists.ez.no http://lists.ez.no/mailman/listinfo/components