Re: New #eval directive available

Alex Twisleton-Wykeham-Fiennes <[email protected]>
Newsgroups gmane.comp.java.webmacro.user
Message-ID <[email protected]>
On Tuesday 12 April 2005 15:35, Keats Kirsch wrote:
> Endre Stølsvik wrote:
> >On Fri, 1 Apr 2005, Keats Kirsch wrote:
> >| I posted the new #eval directive last night, along with a couple of unit
> >| tests for the new functionality.  I'll try to update the Wiki page soon.
> >|
> >| In a nutshell, you can now use Strings containing WMScript, instead of
> >| Templets or other Macros, with #eval.  E.g.,
> >|
> >| [#eval "\$a \$b" using { "a":"Foo", "b":"Bar" }]
> >|
> >| would expand to:
> >|
> >| [Foo Bar]
> >|
> >| If you leave off the "using" clause, the current context will be used,
> >| e.g.,
> >|
> >| #set $a="Foo"
> >| #set $b="Bar"
> >| [#eval "\$a \$b"]
> >|
> >| would give the same result as above.
> >
> >What if I'd like a mix? I want the current context (copied), but I want to
> >"override" this and this and this variable? I see this as an immediate
> >useful feature.
>
> You have two choices: use the $OutVars with a new context, or set and
> restore the variables in the current context.  (I want to keep things as
> simple as possible.)

could you not just clone the $OuterVars container?

something like:-

#set $a = "foo"
#set $b = "bar"
#eval "\#set \$myOuterVars = \$OuterVars.clone() \
       $myOuterVars.b = "not bar" \
       #eval "\$a \$b" using $myOuterVars""

Of course that is all a bit obtuse due to the dual nested val and all the 
escaping of params and the like...  As a templet it looks a little bit more 
sensible...

#templet $inner {
  $a $b
}

#templet $outer {
  #set $myOuterVars = $OuterVars.clone()
  #set $myOuterVars.b = "not bar"
  #eval $inner using $myOuterVars
}

#set $a = "foo"
#set $b = "bar"
#eval $outer

However, it doesn't actually work for the following reasons:-

- "#eval $outer" doesn't have a local Context for $outer so I can't get hold 
of the Context to clone it.  
Is there an object in the Context that corresponds to the Context itself?
Or should there always be an $OuterVars available to the templet on the 
grounds that the templet doesn't know whether or not it will have been passed 
a local context?
Alternatively doing this: #eval $outer using { "anything":"anything" } works 
although is ugly.

- #eval $inner using $myOuterVars is rejected despite the fact that 
$myOuterVars is actually a HashMap after being cloned from the OuterVars 
object.  I would have expected this to function, but get a ClassCastException 
so it doesn't appear to be possible at the moment.

If these two issues where easily resolvable and we where to pass in the String 
that contained the code of the inner template to be evaluated then we would 
be able to state this:-

#templet $outer {
  #set $myOuterVars = $OuterVars.clone()
  #set $myOuterVars.b = "not bar"
  #eval $templateCode using $myOuterVars
}

#set $a = "foo"
#set $b = "bar"
#set $templateCode = "\$a \$b"
#eval $outer

which would give us the ability to insert "Context Filters" in between the 
current framework and an arbitrary target template where the wrangling was 
only visible within the context of the target template.

Alex


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id396&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.