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." <gm...@xyris.com> on 2001/01/02 14:26:47 UTC

Context and Nulls

We had a bit of discussion before the holidays, and figure we should revisit
the following :

How should we define the Context handling of null keys and values?  Lets
forget about if we are implemented via a HashMap, a Hashtable or a DB
(because after tonight, you can use and mix all three..)  but how we want
the Context API to be formally defined.

I think :

1) If you try a put( null, obj )  or put( key, null )  or put(null, null)
then nothing should be altered in the context, and conditionally, this would
be logged as a warning. (Condition is a switch in the props file, default
off or on or whatever :)

2) if you do a get( null ) you should be returned null and conditionally
have this logged.

In other words, I can't think of a valid reason to accept null as either key
or value.  One could say that it's meaningful to distinguish between
something being in the context and null, and not being in the context, but I
don't personally see it.  It sounds like we are encouraging a dependency
upon a side effect of sorts.

Further, to keep the implementation of new kinds of contexts easier,  having
these restrictions results in simpler requirements for context
implementation.

geir




Context chaining examples

Posted by Christoph Reck <Ch...@dlr.de>.
Here I want to provide a set of examples for context chaining.

Comments to other issues in this thread are in a separate post.

A. Without
   1. instantiate VelocityContext
   2. populate it
   3. render template
   This has been the form before chaining was possible. It has
   the (small) drawback that the objects and tools placed into 
   it are modifyable (specially problematic within VMs/recursion  
   and #parsed files).

B. Typical inmutable context setup:
   1. instantiate an intial VelocityContext
   2. populate it with global tools/objects (must be thread safe!)
   2a. optionally chain it to protect objects (make it inmutable)
   3. upon each request: clone it
   4. populate it with other tools/objects
   6. remove/mask-out tools/objects depending on security issues
   5. chain it with another VelocityContext to protect objects
   7. render template

C. During macro processing
   8. Add another chained context:
      a) In the VM setup: add a chained context containing only
         the passed VM parameters. Any #set is then local and does
         not affect the parent context. This has an performance 
         impact.
         Geir mentioned something on making the passed parameters
         the only ones that may affect the parent context... I can't
         figure out a sensible/reliable form of doing this.
      b) Via #local($vars...)...#end (This is my preffered way.)
         Here only the $vars parameters to the PD are local and so 
         dropped after the end. All other #sets affect the parent 
         context.
         A local block is added only if the VM requires local vars
         and can be left away for performance reasons - up to the
         designer.
         This requires a LocalContext implementation, but does not
         affect any other Vel feature!
         This would also safely enable Geir's recursion...
      c) Something Geir/Jose are talking about... without chaining?

D. During normal template processing
   Same as C.8.b) above, thus allowing local variables independent 
   of any current context definitions. 
   This is *very* useful whithin #parsed files and safely avoids 
   any conflicts (e.g. to create safe reusable template and macro 
   libraries).
   This is also useful to use variables that do not remain and 
   pollute the context after their use has completed. They disapear 
   after the #end! This is similar to a for(int i;;){int j;...}
   where i and j are local.

Any use I missed?

:) Christoph

Re: Context and Nulls

Posted by Christoph Reck <Ch...@dlr.de>.
My experience shows me these situations where a NULL can happen.

a) The template designer has written an invalid identifyer:
     #set( $foo = $bar.woobie ) 
   where getWoobie() does not exists. here it is sufficient that
   its logged...

b) Sometimes there are existing beans that may return NULL (e.g.
   upon connection timeout, exception, unavailability, etc.), here a:
     #set( $result = $bean.hunt("fox") ) 
   could return NULL and with your proposal would leave the
   $result reference unexpectedly unchanged. 

   - This would require error prone review/rewriting of all objects
   and methods used within the context.

   + If NULL would be allowed as values, a following:
     #if( $result )
        Your hunt returned $result.brown brown foxes and $result.black foxes.
     #else
        You returned with empty hands from your hunt.
     #end
   could be used to gracefully handle the problem.

   A more sensible example within a turbine application would be:
     #set( $cachedObject = $data.Session.getAttribute("name") )
     #if ( !$cachedObject )
        #set( $cachedObject = $Factory.createObject() )
        #set( $dummy = $data.Session.setAttribute("name", $cachedObject) )
        ## rather use #call( $data.Session.setAttribute("name", $cachedObject) )
     #end
     ## now you can use the $cachedObject any way you want...

"Geir Magnusson Jr." wrote:
> 
> We had a bit of discussion before the holidays, and figure we should revisit
> the following :
> 
> How should we define the Context handling of null keys and values?  Lets
> forget about if we are implemented via a HashMap, a Hashtable or a DB
> (because after tonight, you can use and mix all three..)  but how we want
> the Context API to be formally defined.
> 
> I think :
> 
> 1) If you try a put( null, obj )  or put( key, null )  or put(null, null)
> then nothing should be altered in the context, and conditionally, this would
> be logged as a warning. (Condition is a switch in the props file, default
> off or on or whatever :)

+1 for avoiding put( null, obj ) 
-1 for inhibitting put( key, null ).

> 
> 2) if you do a get( null ) you should be returned null and conditionally
> have this logged.

+1 This would be a feasible approach. For development this sould do logs,
whereas in the runtime it could be disabled. Allowing the (template)
developers track problems, and then leave the runtime performant.

> 
> In other words, I can't think of a valid reason to accept null as either key
> or value.  One could say that it's meaningful to distinguish between
> something being in the context and null, and not being in the context, but I
> don't personally see it.  It sounds like we are encouraging a dependency
> upon a side effect of sorts.
> 
> Further, to keep the implementation of new kinds of contexts easier,  having
> these restrictions results in simpler requirements for context
> implementation.

Somebody already said in this list "NULL is your friend".

> 
> geir

:) Christoph