|
From: Alex F. <al...@fi...> - 2011-11-29 12:45:05
|
All,
moving aside from the discussion about hosting and version control of
webmacro, and shifting across to the fixing of the bug (which I will fix in
my github tree, and then backport across to the sourceforge tree if people
want the fix), there are basically two ways to fix it:
1. Change EvalDirective so that when it invokes setMap on the Context
that it has created to invoke the templet on, that it copies the Map before
invoking setMap and then utilises the copy. This copy can then be mutated
by the templet without effecting the original cached parsed Map.
2. Change EvalDirective so that rather than invoking context.setMap, it
instead invokes context.getMap().putAll(argMap) thereby copying the
contents of the cached Map into the Map inside the Context that can then be
invoked.
My personal preference is the second, and I would remove context.setMap
which is only used for EvalDirective. My reasons for wanting to remove the
method are:
1. it feels like an optimisation to avoid copying the Context in
EvalDirective and as a side effect created this bug
2. it doesn't smell very nice to me. I would prefer Context to be
responsible for data that can be contained within itself and letting a 3rd
party drop in an unknown implementation of Map at an unknown point in the
lifecycle of the Context just feels a bit wrong
3. specifically in the context of the fix to EvalDirective - it just
feels wrong that we do the following:
1. Create a Context, that creates an empty Map
2. Create an external Map
3. Copy our cached Map into the external Map
4. replace the Context Map with the external Map
as opposed to:
1. Create a Context, that creates an empty Map
2. copy our cached Map into the Context's Map
Let me know if anyone has any strong feelings about this and I will add in
a fix to my tree...
Alex
On 24 November 2011 17:44, Alex Fiennes <al...@fi...> wrote:
> Dear all,
>
> I have absolutely no idea whether or not there is anybody on this list, or
> if they are whether or not they are interested in things webmacro, so I
> might be talking to myself, but here goes...
>
> First off, I've found a bug. Lets consider the following block of code:
>
> #templet $test {
> Original: $value <br />
> #set $value = $value + 1
> Incremented: $value <br />
> }
> #eval $test using { "value": 1 }
>
> You run this in a servlet and it does what you would expect, ie:
>
> Original: 1
> Incremented: 2
>
>
> However if you reload the page shortly afterwards then you get the
> slightly surprising:
>
> Original: 2
> Incremented: 3
>
>
> which is much less what you would expect.
>
> I've been doing some initial poking around and from what I can see the
> problem is roughly along the lines of:
>
> - the parser compiles the {"value": 1} into a Map and then caches this
> - the EvalDirective passes this very same Map into the Context that is
> used to evaluate the $test templet
> - the $test templet makes changes to it's Context which then changes
> the cached compiled version of {"value": 1}
> - the next time we invoke $test, we pass in what we assume is the
> compiled version of {"value": 1}, but it actually now contains {"value": 2}
>
> If one leaves a pause between reloads and the caching engine discards the
> cached parsed templates then the value returns back to 1.
>
> Now obviously, the EvalDirective should be taking a shallow copy of the
> params before setting this as the Map that is backing the Context that is
> used to evaluate $test.
> I've mocked this up in user space so that I can invoke:
>
> #eval $test using $Vars.copyMap({ "value": 1 })
>
> and I get the expected behaviour, ie the value doesn't increment between
> reloads.
>
> So I'm going to patch EvalDirective to sort this out which brings me onto
> my second point.
> I've been doing a bit of playing around with webmacro myself and I've got
> a clone of the git repository that Guy Bolton-King took of the sourceforge
> CVS repository and this is sitting at
> https://github.com/alex-fiennes/webmacro
> This has been a gentle experiment so far because I haven't found anything
> that is actually broken yet, but come this bug then I suspect that I might
> well start using my branch for production stuff rather than just playing
> around with ideas.
> Who else other than me is still using webmacro and should I just continue
> to work on my github branch and move forwards? Failing that, do people
> want me to backport changes across to sourceforge?
>
> Stuff that I have been initially working on in github is:
>
> - removing the dependencies on the EDU.oswego.cs.dl.util.concurrent
> packages and using the java concurrent packages
> - adding in generics declarations as required so that the package will
> compile cleanly against modern java.
>
> What I am planning to work on is:
>
> - adding in support for invoking varargs methods from inside templates
> - a certain amount of refactoring to use more of google guava
> libraries as appropriate
> - better error reporting on nested templet invocations
>
> If people want to let me know whether or not any of this is of interest to
> anyone then we can work out how to move forwards. If I don't hear back
> from anyone then I will assume that everyone has moved on to new pastures
> and I will just continue down the path outlined above.
>
> Alex
>
> --
> Alex Fiennes
> email: al...@fi...
> mobile: +44 (0)7813 832662
> office: +44 (0)1875 823 310
>
>
>
--
Alex Fiennes
email: al...@fi...
mobile: +44 (0)7813 832662
office: +44 (0)1875 823 310
|