Christoph :

> "Geir Magnusson Jr." wrote:
> [SNIP]
> > 4) We want to handle the app side putting null keys and values into the
> > context w/o throwing our hands up and saying 'let the implementation
decide'
> > or having to sprinkle try{} blocks everywhere.

> OK (but note that null keys isn't really required but can be added
> analogosuly to null values). I see this is aiming at the solution
> proposed below.

No, I don't mean we keep null keys, just that we handle them and drop them.
As long as we return null from a get(null), all is well...

> >
> > 5) We want the chained contexts to be handled in a reasonable way.  I
> > personally feel strongly that to keep things simple and predictable when
> > chaining multiple Context implementations, the chained context should be
> > guaranteed not to be altered - it's read-only.  (Useful property for
> > frameworks that might have a pool of pre-filled tool contexts, for
example.
> > And if the template is altering the context, constraining it to the
local
> > level and letting the app handle it seems the best to me.)

> -0, I can very well imagine VMs updating the parent context (more below).
> Whereas the tools and defaults set up as a base context should be
read-only.

Are we talking about the same thing?

> >
> > One approach would be to make something referred to as 'NULL'.  Note
this
> > isn't the Java 'null', but something that combines B & C above.  I would
> > envision as a singleton Object defined in AbstractContext or elsewhere
that

> Singleton pattern with a private constructor:
 [SNIP]

> > would be placed into the context in place of null, and then would be
used
> > for comparison.  It would :
> >
> > - for #1 above, be available for equality comparison in VTL a la  #if
($foo
> > == NULL)  : which asks "Does $foo have a valid value".  We remove the

> Now it could be simply #if ($foo == $NULL), no change in the parser!

yes, but then we have a 'special' reference we have to document.  If it's a
parser token, then $NULL can be used for other things by the users.

> Note that Jose also proposed a $?foo syntax.

I think it was earlier than that, and soundle thumped down by jon, I think.

> > question "Is it in the Context?" because it's meaningless to a template
> > designer.  I mean, if there is a value for this reference, we can do
> > something with it.  If not, it doesn't matter if it's a null valued key
in
> > the context, or not in there.  The results are the same.  For debugging,
we
> > should have appropriate log messages generated both from the app side
using
> > the Context interface and the template side #set() directive so you can
> > figure out why something == NULL

> Please note that sometimes returing null is desireable:
>  #set( $dummy = $hastable.put("KEY", "woobie") )
> Do I have to place a bang into $!hastable to avoid a message?

No, you don't have to put a bang. That is only for rendering, and you are
not rendering when you are on the RHS of a #set().

And you can return a java null, and we will turn it into the NULL,
internally.  I guess I must not have been clear.  Just like the app-level
context API would convert java-null args to put(), get() to NULL internally,
we would do the same in #set() for java-null returning refs and methods, as
well as 'invalid' method invocations.

> >
> > - for #2 above, would handle the case when we do a null assignment in a
> > #set().  Internally, we would just put the NULL object into the context
for
> > that reference, and log it if in debug mode (or whatever)

> It's OK if the AbstractContext handles the NULL-object putting, and there
> are no other means of accessing the HashMap behind from the application.

AbstractContext has no storage implementation. It's abstract.
VelocityContext does, and yes, I think that AbstractContext should take care
of it so the code doesn't have to be reimplemented each time you derive from
AbstractContext.

> [snip]
> - for #5, we preserve the idea that chained contexts are immutable (if we
> decide we want that), and by putting NULL into the 0th or local context,
we
> would functionally 'remove' the chained value so it won't be accessable.
> because we mask it : the local get() returns the NULL object.

> -0 for immutable chained contexts. It should be the
implementation/application
> to decide that (more below).

Yuck.  Agreed for app-defined context implementations (that's one of the
points of all this : application freedom to hang yourself...)  But the Vel
provided impls should not allow chained context alteration, I believe.  I
think altering the chained context is a special thing, application specific,
will be rarely used, and better be done by a clueful person.

> >
> > This would be a useful feature with chaining : a framework could fill a
> > context with a complete toolset, and then a permission layer/manager
could
> > chain that context and 'mask off' the tools that aren't allowed for a
given
> > user/session/whatever.

> exactly!

But you do it by chaining the base context, and then adding nulls -> NULL to
mask off in the 0th level context.  You can then use that, or pass it to
someone else to chain with.  You don't actually alter the context that was
passed to you.  You do have that option, of course.  If I hand you a
context, you can just diddle with it directly.  But if you chain it, or I
chain it before giving it to you, I can protect it from you.

> >
> > What's missing?
> >

> Missing the notion of a mutable chained contexts and a #local...#end
directive.

Look, you have the freedom to implement mutable chained contexts, or set up
your framework so each layer can alter directly, chain and alter with
masking, or chain to protect and pass it down...  and since AbstractContext
has a 'getChainedContext()' method to extract (I threw that in there...
anyone hate it?  I sort of do now...  :) the inner context, you can at app
level screw with the inner context.

Can you give an example of functionality you wont have if the inner context
is shielded from put()s by the 0th level context?

> >
> > Well, that seems to be a java-side function rather than template side.
> > There is a keys() method to Context, so you should be alble to get an
array
> > of keys. And then you can do a #if($foo == NULL) on the template side.

> yes, I will probably need a PD to make keys() visible in the template
> (to dump the context using a template or WM!).

Really?  Why not just do soemthing like

  context.put("contextkeys", context.getKeys() );

before merging????

Its easier to add a PD?


> >
> > > Now for the context chaining it will be necessary to differentiate
> > > between a no-value and no-definition states. So there is a reason
> > > for NULL values (Hi NULL friends :).
> >
> > I don't think we need to differentiate in the template.  Logging them,
yes.
> > So the concept of a NULL would work if it covered both.  As the template
> > author, you just want to know if it's usable, right?

> OK, but I would like a way to avoid logs (using bang? - example above).

Turn of the logging?  Just a thought...

> Im missing a form for WMs to update/return values. I tried to explain that
> above. I know that VTL is not a programming language, but I believe this
> is general enough. The mutable chained contexts and a #local...#end
directive
> would fix this.

The local/end thing will be fixed soon w/o new directives (I hope:)  There
are a couple of related issues I want to knock off in one fell swoop.

It's not a proggie lang.  When you say 'return values' do you mean objects
and such?  Or can it just alter the context for you?

geir

Reply via email to