You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by "Geir Magnusson Jr." <ge...@optonline.net> on 2000/11/28 07:01:28 UTC

Interpolation

We have added interpolation for string literals.   It may offend some of
you purists, so consider it a proposal.  Yes, you can turn it off. Here
is how it works :

  You can stuff anything you want into a string literal and if 
  stringliterals.interpolate = true (the default) it will interpolate.

There.  Shortest announcement yet.

This is pretty much the most scary, powerful feature we have added,
well, since Velocimacros. Its scary at first blush, but if you control
the jerking-knees and think for a sec, it isn't so bad.  You really
can't hurt yourself with it, as all that you can do is parse valid
VTL.   There is a small performance penalty, but that will go away after
we optimize it.

Best shown with examples :

1) Simple string interpolation:

   #set $one = 1
   #set $two = 2
   #set $three = 3
   #set $out1 = "${one}${two}${three}"
   #set $out2 = "$one $two $three"
   $out1
   $out2

output :

   123
   1 2 3

2) How about a directive?  Sure. We're wacky!

  #set $foo = "test.txt"
  #set $out = "#include( $foo )"
  $out

output :
   
   I am the contents of test.txt.


3) For our next trick, lets interpolate a.... VelociMacro!

   #macro( interpfoo )
     Hi, I'm a VM!
   #end

   #set $ivm = "#interpfoo()"
   $ivm

output :

   
   Hi, I'm a VM!


4) And now, for something completely different :

   #set $code = "#if(false) True #else False #end"
   $code

output :
  
   False

or

  #set $arr = ["a","b","c"]
  #set $foo = "#foreach($a in $arr) >$a< #end"
  $foo

output

   >a<  >b<  >c< 


Test bed example is interpolate.vm, and it can be turned off with the
stringliteral.interpolate property.

Enjoy.  Comments and questions welcome as always.

geir

-- 
Geir Magnusson Jr.                               geirm@optonline.com
Dakota tribal wisdom: "when you discover you are riding a dead horse,
the best strategy is to dismount."

Re: Interpolation

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
Fedor Karpelevitch wrote:
> 
> Hi!
> 
> I actually like this a lot, cause I was thinking of something really
> similar. I think this can help get read of VMs and directives <grin>

Not likely :)

> Couple of thoughts:
> 
>   - What about such string producing Template object which you can then
> operate on ( call methods on and pass as parameter to others' methods )?

I never quite know what to say here... :)

>   - It would be useful to distinguish between plain strings and "parsed"
> strings. What about using different delimeter? Single quotes? colons?
> anything else?

Maybe.  No colons.  I can try single quotes, ala Perl.  You can also use
the VTL escape mechanism (\$foo) to achieve the same. (I hope...)

>   - I would also love to be able to operate on a literal a on a real
> object, same way as on reference. As I can do this in Java:
>      "A String".length();
>   I'd like to be able to do in Vel smth like:
>      $'A Template'.foreach($list, "elem")

I know. Again, I am pretty speechless. ;)

geir


> Geir Magnusson Jr. wrote:
> 
> > We have added interpolation for string literals.   It may offend some of
> > you purists, so consider it a proposal.  Yes, you can turn it off. Here
> > is how it works :
> >
> >   You can stuff anything you want into a string literal and if
> >   stringliterals.interpolate = true (the default) it will interpolate.
> >
> > There.  Shortest announcement yet.
> >
> > This is pretty much the most scary, powerful feature we have added,
> > well, since Velocimacros. Its scary at first blush, but if you control
> > the jerking-knees and think for a sec, it isn't so bad.  You really
> > can't hurt yourself with it, as all that you can do is parse valid
> > VTL.   There is a small performance penalty, but that will go away after
> > we optimize it.
> >
> > Best shown with examples :
> >
> > 1) Simple string interpolation:
> >
> >    #set $one = 1
> >    #set $two = 2
> >    #set $three = 3
> >    #set $out1 = "${one}${two}${three}"
> >    #set $out2 = "$one $two $three"
> >    $out1
> >    $out2
> >
> > output :
> >
> >    123
> >    1 2 3
> >
> > 2) How about a directive?  Sure. We're wacky!
> >
> >   #set $foo = "test.txt"
> >   #set $out = "#include( $foo )"
> >   $out
> >
> > output :
> >
> >    I am the contents of test.txt.
> >
> >
> > 3) For our next trick, lets interpolate a.... VelociMacro!
> >
> >    #macro( interpfoo )
> >      Hi, I'm a VM!
> >    #end
> >
> >    #set $ivm = "#interpfoo()"
> >    $ivm
> >
> > output :
> >
> >
> >    Hi, I'm a VM!
> >
> >
> > 4) And now, for something completely different :
> >
> >    #set $code = "#if(false) True #else False #end"
> >    $code
> >
> > output :
> >
> >    False
> >
> > or
> >
> >   #set $arr = ["a","b","c"]
> >   #set $foo = "#foreach($a in $arr) >$a< #end"
> >   $foo
> >
> > output
> >
> >    >a<  >b<  >c<
> >
> >
> > Test bed example is interpolate.vm, and it can be turned off with the
> > stringliteral.interpolate property.
> >
> > Enjoy.  Comments and questions welcome as always.
> >
> > geir

-- 
Geir Magnusson Jr.                               geirm@optonline.com
Dakota tribal wisdom: "when you discover you are riding a dead horse,
the best strategy is to dismount."

Re: Interpolation

Posted by Fedor Karpelevitch <fe...@home.com>.
Hi!

I actually like this a lot, cause I was thinking of something really 
similar. I think this can help get read of VMs and directives <grin>
Couple of thoughts:

  - What about such string producing Template object which you can then 
operate on ( call methods on and pass as parameter to others' methods )?
  - It would be useful to distinguish between plain strings and "parsed" 
strings. What about using different delimeter? Single quotes? colons? 
anything else?
  - I would also love to be able to operate on a literal a on a real 
object, same way as on reference. As I can do this in Java:
     "A String".length();
  I'd like to be able to do in Vel smth like:
     $'A Template'.foreach($list, "elem")

(assuming Template has foreach() method)

What do you think?

fedor.

Geir Magnusson Jr. wrote:

> We have added interpolation for string literals.   It may offend some of
> you purists, so consider it a proposal.  Yes, you can turn it off. Here
> is how it works :
> 
>   You can stuff anything you want into a string literal and if 
>   stringliterals.interpolate = true (the default) it will interpolate.
> 
> There.  Shortest announcement yet.
> 
> This is pretty much the most scary, powerful feature we have added,
> well, since Velocimacros. Its scary at first blush, but if you control
> the jerking-knees and think for a sec, it isn't so bad.  You really
> can't hurt yourself with it, as all that you can do is parse valid
> VTL.   There is a small performance penalty, but that will go away after
> we optimize it.
> 
> Best shown with examples :
> 
> 1) Simple string interpolation:
> 
>    #set $one = 1
>    #set $two = 2
>    #set $three = 3
>    #set $out1 = "${one}${two}${three}"
>    #set $out2 = "$one $two $three"
>    $out1
>    $out2
> 
> output :
> 
>    123
>    1 2 3
> 
> 2) How about a directive?  Sure. We're wacky!
> 
>   #set $foo = "test.txt"
>   #set $out = "#include( $foo )"
>   $out
> 
> output :
>    
>    I am the contents of test.txt.
> 
> 
> 3) For our next trick, lets interpolate a.... VelociMacro!
> 
>    #macro( interpfoo )
>      Hi, I'm a VM!
>    #end
> 
>    #set $ivm = "#interpfoo()"
>    $ivm
> 
> output :
> 
>    
>    Hi, I'm a VM!
> 
> 
> 4) And now, for something completely different :
> 
>    #set $code = "#if(false) True #else False #end"
>    $code
> 
> output :
>   
>    False
> 
> or
> 
>   #set $arr = ["a","b","c"]
>   #set $foo = "#foreach($a in $arr) >$a< #end"
>   $foo
> 
> output
> 
>    >a<  >b<  >c< 
> 
> 
> Test bed example is interpolate.vm, and it can be turned off with the
> stringliteral.interpolate property.
> 
> Enjoy.  Comments and questions welcome as always.
> 
> geir


Re: Interpolation

Posted by Christoph Reck <Ch...@dlr.de>.
Hi Geir, this is simply great! You're an ace!

Yep one can exagerate things. Now with interpolation, it is sufficient 
to me...

BTW "interpolation" is a bit misleading... "embedding" could be more
apropiate. Other names are also thinkable: "RHS directives", 
"evaluation", etc. :)

"Geir Magnusson Jr." wrote:
> 
> Fedor Karpelevitch wrote:
> >
> > Hi!
> >
> > I actually like this a lot, cause I was thinking of something really
> > similar. I think this can help get read of VMs and directives <grin>
> 
> Not likely :)

Well, imagine, getting rid of either '#' or '$' now is really possible...
Would simplify things a lot (maybe, to be optically good, you could leave
the '#' for comments...:
  #**
   * This macro appends two strings.
   * @param a The first string.
   * @param b The second string.
   * @return The strings of a and b catenated.
   **#
  $macro(append, $a, $b, "$a$b")
  # this is a simple comment describing something...
  $set(bar, "bar")
  $set(foo, "foo")
  # now we invoke the macro as a RHS...
  $set(result, $append($foo, $bar))
  #* Now this is orthogonal! 
   * But not likely to be implemented at this stage!
   *#

Doing interpolation by hand would have required a ContextTool:
  #set $result = $Template.create("\#someVM(\$to,\$evaluate)").merge()
or (a #parse replacement...)
  #set $result = $Template.load($filename).merge()

> 
> > Couple of thoughts:
> >
> >   - What about such string producing Template object which you can then
> > operate on ( call methods on and pass as parameter to others' methods )?
> 
> I never quite know what to say here... :)

I don't get it either... 

Note that -per definition- VMs return strings. Only context tools can
return object references, and therefore you can then directly invoke the
methods on them (see Template example above).

Isn't this enough:
  #set $bar = "foo"
  Length = $foo.length()
And with the additional VM feature?
  #macro(length, $string)$string.length()#end
  #set $bar = "foo"
  Length = "#length($foo)"

Does it need quotes around the VM call above? Maybe this is OK, because
macros can -per definition- only return strings! but consider:
  #macro(length, $string)$string.length()#end
  #set $foo = "foo"
  #set $bar = "bar"
  #set $return = "the length of $foo$bar is #length("$foo$bar")"
is then not possible... :(  Maybe the single quoting as mentioned
below can help on this... :)

> 
> >   - It would be useful to distinguish between plain strings and "parsed"
> > strings. What about using different delimeter? Single quotes? colons?
> > anything else?
> 
> Maybe.  No colons.  I can try single quotes, ala Perl.  You can also use
> the VTL escape mechanism (\$foo) to achieve the same. (I hope...)

What I'm missing is:
  #set $foo = '"this string is quoted"'
  #set $bar = "$foo AND 'this one is single-quoted'"
(there is currently no straightforwad way of creating strings with
 double quotes...)

How do I create a long string?
OK, now it can be done with either interpolation or VMs...
  #set $foo = ["abc", "def", "ghi"]
  #macro(append, $a, $b)$a$b#end
  #set $bar = "The foo alphabet is: "
  #foreach($f in $foo) 
    ## does the next need quotes around the VM call?
    #set $bar = #append($bar, " $f")
  #end
or
  #set $bar = "The foo alphabet is: #foreach($f in $foo) $f#end"

Wow, isn't this latter one cool!

> 
> >   - I would also love to be able to operate on a literal a on a real
> > object, same way as on reference. As I can do this in Java:
> >      "A String".length();
> >   I'd like to be able to do in Vel smth like:
> >      $'A Template'.foreach($list, "elem")
> 
> I know. Again, I am pretty speechless. ;)
Isn't this enough:
  #set $bar = "foo"
  Length = $foo.length()
Strings are awfully restrictive in Java (see http://www.jwz.org/doc/java.html)
 and such a feature will only have an impact on inline created strings.
 Therefore the #set and $reference way is much more general and 
 powerfull... :)

> 
> geir


:) Christoph