felix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Guillaume Nodet <gno...@gmail.com>
Subject Re: Gogo
Date Tue, 18 Aug 2009 14:46:28 GMT
On Tue, Aug 18, 2009 at 09:17, Derek Baum <derek.baum@paremus.com> wrote:

> 2009/8/17 Guillaume Nodet <gnodet@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:
> karaf@root> <echo a; echo b> | tac
> ab
> karaf@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
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
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
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.
> >
> >

Guillaume Nodet
Blog: http://gnodet.blogspot.com/
Open Source SOA

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message