jstrachan | 27 Jan 06:44 2005

Re: Builder ideas

Guillaume Laforge wrote:

> jastrachan@... wrote:
>> class SwingBuilder {
>>   JFrame frame() { ... }
>>   JPanel panel() {...}
>> }
>> and we wrote code something like
>> with (new SwingBuilder()) {
>>    frame {
>>       pan()  // syntax error, no such method
>>    }
>> }
> In fact, currently, in Groovy classic, we're calling 
> standard/statically-typed methods first. Mr T is a bit angry at me 
> because of that change in the semantics of method invokation.
> Thus, even with the classic builders, if you have frame() and panel() 
> methods, they are already called like you suggest them to be.
> This makes it possible to write builders in Groovy, which calls methods 
> on itself, otherwise, it wasn't possible.
> But because of that, I broken the possibility of intercepting methods 
> like toString() notify() or other methods...
> :-(

Agreed. This highlights one of the problems of intercepting all method 
invocations to implement markup.

What we could do is have a Markup/Builder interface that the markup 
invokes; then classes can implement the specific Markup interface if 
they want - or we could provide an implementation which delegates Markup 
method calls to methods on the builder object. Then we don't have to 
mess with the core method invocation mecahnism.


if the interface was something like

interface Markup {
   Object onElement(String name, Map attributes, Closure content)

we could have an implementation thats something like...

/** Delegates method calls to some Java object */
class DelegateMarkup implements Markup {
   Object delegate

  Object onElement(String name, Map attributes, Closure content) {
    // do something clever with the arguments
    arguments = new Object[] { attributes, closure }

    return InvokerHelper.invokeMethod(delegate, object, arguments)

Then the groovy markup pseudocode could be something like...

Object builderExpression = ... // the builder
Markup builder = null
if (builderExpression instanceof Markup) {
   builder = builderExpression as Markup
else {
   builder = new DelegateMarkup(builderExpression)

Then we could use the swing markup example at the top of this mail, 
where SwingBuilder might not need to explicitly implement the Markup