Couldn't resist the title...

Ok - here is the issue with the problem that Paulo brought up :

There are lots of reasons why the VMs got complicated (the current
implementation is the 2nd implementation) and I won't go into them
here.  I'm too tired, it's boring, and irrelevant.  

However, doing the 2nd impl provided the following dilemma - what do you
do when a passed in reference doesn't correspond to anything in the
context?

Some history - in the beginning, Velocimacros were a very simple idea -
it was as if you had the VTL code with the passed-in arguments pasted
into place in the VTL where the VM was.  Example :

#macro( mymacro $a )
  mymacro:$a
#end

so using

stuff in template
#mymacro( $lala.woogie() )
more stuff in template

was like you had simply

stuff in template
  mymacro:$lala.woogie()
more stuff in template

in the template.  This initial approach was deemed ok, and kept many a
bloodpressure reading at safe levels (the idea of VMs wasn't too popular
at first...).

Then people decided they wanted to do two things - call other VMs (and
recurse) and pass in strings :

#macro( callee $a )
  $a
#end
#macro( caller $a )
  #callee( $a )
#end

so then if you had

#caller( "Hi Mom!")

it would be like having

#callee( Hi Mom )

which would become... whoops!  See the problem?  Because the VM was like
a 'paste of value', you had to remove the " characters, so all of a
sudden, the VM engine couldn't find a VM 'callee' with 2 args.

Another issue was recursion - I won't give an example, but you could
easily clobber your own context, as there was no notion of 'stack' or
'local variable' or any of the usual nicities you have in a recursion-
supporting environment.

Ok.  So with the 'new' implementation, I had a decision to make - what
to do about the null reference passed in.  Because

#macro( printme $a )
->$a<-
#end

when called with a null reference

#printme( $notincontext )

previously behaved as if you had 

->$notincontext<-

pasted into your template.

However, due to how things work internally, it was neigh impossible to
tell if the request for the value of the wrapped arg was for deducing
the value (as in an #if() ) or it was rendering.

Therefore, I decided ad hoc (I was probably real tired, and I did note
in the code, and posted to the list...) that to maintain full backwards
compatibility, I would make it such that the behavior was unchanged, and
for reasons that I can only ascribe to utter momentary derangement, it
would be this way for multi-segmented reference calls (method or
property) like $foo.bar

So I propose : 

That I fix it.

The change would be -

When you call a VM with a non-existant reference, the rendered output
will be simply the *literal form of the corresponding VM arg* if
rendered in the VM, and #if() will work correctly - namely the value is
null.

An example : 

#macro( foo $a )
 ->$a<-#if($a)yes#end
#end

When called with a real value :

#set($lala = "hello")
#foo($lala)

output

->hello<-yes

and when called with something not in the context

#foo($notincontext)

output

->$a<-

That would be the result of the change.

Sorry about the long post, but I want to put this to bed quickly.

geir

-- 
Geir Magnusson Jr.                           [EMAIL PROTECTED]
System and Software Consulting
Developing for the web?  See http://jakarta.apache.org/velocity/
You have a genius for suggesting things I've come a cropper with!

Reply via email to