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
>

Reply via email to