Velocity
  1. Velocity
  2. VELOCITY-706

Method arguments should allow an evaluation context

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.x
    • Fix Version/s: 2.x
    • Component/s: Engine
    • Labels:

      Description

      It should be possible to write things like:

      $myref.mymethod( $foo + $bar )

      that is, to give method arguments an evaluation context

        Issue Links

          Activity

          Hide
          Byron Foster added a comment -

          Agreed, I think it would be pretty straight forward to add an entire velocity expression as a parameter so something like this would also be possible:

          $myref.mymethod($foo + $bar > $foobar)

          Of course mymethod would have to take boolean.

          Show
          Byron Foster added a comment - Agreed, I think it would be pretty straight forward to add an entire velocity expression as a parameter so something like this would also be possible: $myref.mymethod($foo + $bar > $foobar) Of course mymethod would have to take boolean.
          Hide
          Steve O'Hara added a comment -

          I suspect if 752 can be fixed then this feature becomes available as part of that fix

          Show
          Steve O'Hara added a comment - I suspect if 752 can be fixed then this feature becomes available as part of that fix
          Hide
          Constantine Nosovsky added a comment - - edited

          Hi, as I mentioned in my letter to dev mailing list [1] I would love to take a part in GSoC 2012 and to implement functionality described in this issue.
          I have several ideas and questions so far. I've written a small TODO list to divide this issue into several subtasks.
          1. A tree of operations should be built for each evaluation.
          2. Trees should be cached, because we don't want to parse the string to be evaluated each time we need it (e.g. if it is inside of foreach loop).
          3. We need to define the life cycle of this cache. I think it may grow pretty large and increase memory usage a lot. The cache may have a scope, or another good strategy is to have global cache which uses SoftReferences. Also it would be nice to estimate probability of using one or the other expression and range them for garbage collection.
          4. In order to have cache expression strings should be normalized, I mean that ($var.field1[2] + $var2)5 and $var1($var2+$var3) are pretty much similar. I think that can be achieved by applying Reverse Polish Notation.
          5. Specifications of this evaluation context should be created, I mean a set of operators, possible types of arguments and so on.
          6. Is it reasonable to have functionality which allows to search for already known subexpressions (e.g. $a+$b is subexpression of ($c + $d)/$e) ? This might be quite slow and I believe that expressions to evaluate are normally consist of maximum 5-7 operations, so search might take more time than just plain building of operations tree.
          Please tell me whether these ideas are correct. I'd like to discuss each of them with you.
          I'm not really sure if we need to use some Java specific classes (like javax.script.ScriptEngine) or other third party tools for evaluating expressions or is it better to implement all the system by ourselves?
          Also I have not yet started to explore the source code of Velocity Engine, would you give me some directions?
          One more question regarded to the GSoC. How to officially apply, I mean make an official proposal of my candidacy for this idea?

          [1] - http://mail-archives.apache.org/mod_mbox/velocity-dev/201203.mbox/%3C1332792130.3144.82.camel@localhost.localdomain%3E

          Show
          Constantine Nosovsky added a comment - - edited Hi, as I mentioned in my letter to dev mailing list [1] I would love to take a part in GSoC 2012 and to implement functionality described in this issue. I have several ideas and questions so far. I've written a small TODO list to divide this issue into several subtasks. 1. A tree of operations should be built for each evaluation. 2. Trees should be cached, because we don't want to parse the string to be evaluated each time we need it (e.g. if it is inside of foreach loop). 3. We need to define the life cycle of this cache. I think it may grow pretty large and increase memory usage a lot. The cache may have a scope, or another good strategy is to have global cache which uses SoftReferences. Also it would be nice to estimate probability of using one or the other expression and range them for garbage collection. 4. In order to have cache expression strings should be normalized, I mean that ($var.field1 [2] + $var2) 5 and $var1 ($var2+$var3) are pretty much similar. I think that can be achieved by applying Reverse Polish Notation. 5. Specifications of this evaluation context should be created, I mean a set of operators, possible types of arguments and so on. 6. Is it reasonable to have functionality which allows to search for already known subexpressions (e.g. $a+$b is subexpression of ($c + $d)/$e) ? This might be quite slow and I believe that expressions to evaluate are normally consist of maximum 5-7 operations, so search might take more time than just plain building of operations tree. Please tell me whether these ideas are correct. I'd like to discuss each of them with you. I'm not really sure if we need to use some Java specific classes (like javax.script.ScriptEngine) or other third party tools for evaluating expressions or is it better to implement all the system by ourselves? Also I have not yet started to explore the source code of Velocity Engine, would you give me some directions? One more question regarded to the GSoC. How to officially apply, I mean make an official proposal of my candidacy for this idea? [1] - http://mail-archives.apache.org/mod_mbox/velocity-dev/201203.mbox/%3C1332792130.3144.82.camel@localhost.localdomain%3E
          Hide
          Nathan Bubna added a comment -

          Templates are already being parsed into an AST and caching of that complete AST is already a solved problem.

          Your task amounts to two things: get those expressions parsed and then get them evaluated prior to the method call.

          To start, i would look into how Velocity is using JavaCC (see the org.apache.velocity.runtime.parser package and the Parser.jjt file).

          Also familiarize yourself with how method calls are resolved and executed.

          Last, be aware that VELOCITY-819 will be updating the parser generation process shortly. You might consider applying that patch locally. I expect to find time to push it into the trunk this weekend or early next week, though i hope someone else beats me to it. I'm too damn busy these days...

          Show
          Nathan Bubna added a comment - Templates are already being parsed into an AST and caching of that complete AST is already a solved problem. Your task amounts to two things: get those expressions parsed and then get them evaluated prior to the method call. To start, i would look into how Velocity is using JavaCC (see the org.apache.velocity.runtime.parser package and the Parser.jjt file). Also familiarize yourself with how method calls are resolved and executed. Last, be aware that VELOCITY-819 will be updating the parser generation process shortly. You might consider applying that patch locally. I expect to find time to push it into the trunk this weekend or early next week, though i hope someone else beats me to it. I'm too damn busy these days...
          Hide
          Nathan Bubna added a comment -

          Oh, and to be clear, any expression that works as the RHS of a #set( $foo = expr ) call should be allowed. And complicated caching/searching/analyzing of expressions is out of scope (at least at the outset), as i'll bet that those will cost more in performance and developer mindshare than they are worth.

          If you find you've accomplished the main goals, then you can start running performance tests and looking for ways to optimize things, if you are inclined. But no performance-optimizing code should be written until you have a functional implementation that you can measure.

          Show
          Nathan Bubna added a comment - Oh, and to be clear, any expression that works as the RHS of a #set( $foo = expr ) call should be allowed. And complicated caching/searching/analyzing of expressions is out of scope (at least at the outset), as i'll bet that those will cost more in performance and developer mindshare than they are worth. If you find you've accomplished the main goals, then you can start running performance tests and looking for ways to optimize things, if you are inclined. But no performance-optimizing code should be written until you have a functional implementation that you can measure.
          Hide
          Claude Brisson added a comment -

          Doesn't work with macros, only with Java method calls. But it may be better this way, since expressions as macro arguments could have many side effects.

          Show
          Claude Brisson added a comment - Doesn't work with macros, only with Java method calls. But it may be better this way, since expressions as macro arguments could have many side effects.

            People

            • Assignee:
              Unassigned
              Reporter:
              Claude Brisson
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development