Many of the current tests use <> when it is not needed, so the problem with extra evaluations could be removed by improving the tests.
As the use of <> is not the intent of the test, it should be written without <> assertEquals("ca b", c.execute("e = { echo c$args } ; e a b | capture")); Derek 2009/8/18 Guillaume Nodet <gno...@gmail.com>: > Another example taken from the existing test suite: > > assertEquals("ca b", c.execute("e = { echo c$args } ; <e a b | > capture>")); > > This test currently works fine. > > When extracting the patch for FELIX-1498, this one and the two following > ones are the only one to fail. > The reason is again caused by the fact that a single argument won't cause > any exception if it's not a command. > This wasn't a problem because "ca b" is simply returned, but by splitting > it, it becomes more evident that the result is evaluated, which is not the > intent of the test. > > On Tue, Aug 18, 2009 at 16:46, Guillaume Nodet <gno...@gmail.com> wrote: > >> >> >> On Tue, Aug 18, 2009 at 09:17, Derek Baum <derek.b...@paremus.com> wrote: >> >>> 2009/8/17 Guillaume Nodet <gno...@gmail.com> >>> >>> > >>> > So in short, the patch does the following: >>> > * replace <> with $() >>> > * use ( ) for grouping commands when on the edge of the command >>> > * make the number of evaluation predictable >>> > * have a syntax and semantic which is mostly (fully) in sync with bash >>> > * re-evaluate / split expanded arguments that are not quoted >>> >>> >>> >>> I can still see no reason for having () and $() as two separate operators. >>> This unncessarily compllicates syntax without adding any new capability. >>> >>> You previously gave the following example to demonstrate the need for a >>> separate grouping operator: >>> >>> >The grouping operator is imho needed to be able to order pipes and >>> columns: >>> > (echo a ; echo b) | tac >>> > echo a ; (echo b | tac) >>> >>> However, this example works fine with the existing <> execution quotes: >>> >>> ka...@root> <echo a; echo b> | tac >>> ab >>> ka...@root> echo a; <echo b | tac> >>> a >>> b >>> >>> Do you have any other example or use case that demonstrates the need for a >>> separate grouping operator? >>> >>> () in bash is NOT only used for grouping - it executes the command within >>> (), just like the existing <>. >>> $() in bash executes and captures stdout into a string - equivalent to >>> <command args | tac> in gogo. >>> >> >> Well the key difference between those operators in bash is the number of >> times the evaluation happen. >> >> ( ) does not change the number of times a command will be evaluated, that's >> why i call it grouping. >> What i mean is that if you remove the ( ), the commands will be executed >> the same number of time. >> echo a => echo a >> ( echo a ) => echo a >> ( ( echo a ) ) => echo a >> All of those will produce the same result. >> >> $( ) will increment the number of evaluation each time it's used, and is >> therefore not idemptotent. >> echo echo echo a => echo echo a >> $(echo echo echo a) => echo a >> $( $( echo echo echo a) ) => a >> >> I don't really see how we can conflate both operators using < > or any >> other syntax. >> With the current state of gogo, you're not really sure how many times >> evaluation will happen. >> >> >>> >>> To try to understand the need for separate () and $() operators, I have >>> taken the gogo TestParser.java from the FELIX-1471.patch and replaced both >>> $() and () with <>. I then ran the test against the unpatched code. >>> >>> All tests worked except some newly added tests within >>> testGroupingAndEvaluation() like: >>> >>> assertEquals("a", c.execute("<echo echo a>") + ""); >>> >>> This fails because <echo echo a> evaluates to the String "echo a", which >>> is >>> then evaluated as a command and the command 'echo a' is not found. >>> >>> assertEquals("a", c.execute("$(echo echo a)") + ""); >>> >>> This works because of the complex re-parsing done by $() that you describe >>> below. >> >> >> Right, and I think this reparsing of arguments should be done anyway. So >> maybe we need a separate jira for that one. >> >> I think I understood where our uncomprehension comes from. I first started >> to have a look at FELIX-1325 (throwing an exception when the can't be found, >> even if it has no arguments). The problem is that all those issues are >> linked. >> What you describe above works only because when you have a single token on >> the command line and that no command is found, the token is simply returned. >> This means that in all the above examples, the number of evaluation is not >> really important, because executing "a" will return "a". >> This hides some real issues imho, as the following tests, that all pass on >> trunk show: >> >> assertEquals("echo echo", c.execute("echo echo echo")); >> assertEquals("echo", c.execute("<echo echo echo>")); >> assertEquals("", c.execute("<<echo echo echo>>")); >> >> assertEquals("echo a", c.execute("echo echo a")); >> assertEquals("a", c.execute("<echo echo a>")); >> assertEquals("a", c.execute("<<echo echo a>>")); >> >> >> So the behavior of < > is that it run the command(s) inside it *and* >> evaluates it. It's not only grouping. >> >> Now, let's take an example: >> >> assertEquals("a", c.execute("echoout \"a\nb\" | grep a | >> capture")); >> assertEquals("b", c.execute("echoout \"a\nb\" | grep b | >> capture")); >> assertEquals("ab", c.execute("<echoout \"a\nb\" | grep a | capture> >> ; <echoout \"a\nb\" | grep b | capture> | capture")); >> >> assertEquals("", c.execute("<echoout \"echo\ngrep\" | grep echo | >> capture> ; <echoout \"echo\ngrep\" | grep grep | capture> | capture")); >> >> The first two tests are ok. The third test is equivalent to "test1 ; test2 >> | capture". >> Remember that atm ';' takes precedence over '|'. >> >> Now the last test is the same as the third one, but with different values. >> The output should be "echogrep", but isn't, due to the additional >> evaluation. >> The third test would also fail if we apply FELIX-1325 afaik. >> >> >>> >>> In bash, if you need to re-parse some text, you use the 'eval' command: >>> >>> $ eval $(echo echo '$HOME') >>> /Users/derek >>> >>> We could take exactly the same approach in gogo, by adding a simple eval >>> command for use on the rare occassions when it is required. >>> >>> Derek >>> >>> >>> >>> > >>> > >>> > I'm happy to discuss things further, but the major problem is related to >>> > make the evaluation predictable, which sounds easy, but is not really >>> ... >>> > And this require to re-evaluate / split the expanded arguments. >>> > See the following example: >>> > assertEquals("a", c.execute("$($(echo echo echo a)) | capture")); >>> > The "echo echo echo a" command is executed and prints "echo echo a". >>> This >>> > result is inside $() so it has to be interpreted as a full command line, >>> > not >>> > as a single argument which would be a string "echo echo a" as this would >>> > return a command not found. >>> > >>> > >>> >> >> >> >> -- >> Cheers, >> Guillaume Nodet >> ------------------------ >> Blog: http://gnodet.blogspot.com/ >> ------------------------ >> Open Source SOA >> http://fusesource.com >> >> >> > > > -- > Cheers, > Guillaume Nodet > ------------------------ > Blog: http://gnodet.blogspot.com/ > ------------------------ > Open Source SOA > http://fusesource.com >