[prev in list] [next in list] [prev in thread] [next in thread] 

List:       groovy-dev
Subject:    Re: [groovy-dev] Progress with MetaClass
From:       Alan <alan-groovy-dev () engrm ! com>
Date:       2005-10-30 0:00:17
Message-ID: 20051030000017.GD27901 () maribor ! izzy ! net
[Download RAW message or body]

* John Wilson <tug@wilson.co.uk> [2005-10-29 11:10]:
> 
> On 29 Oct 2005, at 03:59, Alan wrote:
> 
> >>>There are more of these methods than I'm comfortable with. If and
> >>>when we change the way we do method dispatch I think we should look
> >>>at these methods to see if we can rationalise them - there may well
> >>>be overlap.

> >Think I'll expand...
> >
> >public interface Function
> >{
        
Subtract one from all of these, by the way.

> >    public static final int STATIC_METHOD   = 1;
> >    public static final int CONSTRUCTOR     = 2;
> >    public static final int METHOD          = 3;
> >    public static final int CLOSURE         = 4;
> >    public static final int PROPERTY_SET    = 5;
> >    public static final int PROPERTY_GET    = 6;
> >
> >    Object call(Object target,
> >                Class[] types,
> >                Object[] parameters);
> >}
> 
> I'm afraid I don't see the point of doing this. I just have to put a  
> switch statement in my call implementation which decodes the type of  
> call. I have to deal with the possiblility that target is -1 or  
> 10000. It seems to make things more complicated not simpler.

Most implementations of node trees have a common node root that
has a type switch. This is because the similiarities are the same.

Switching on the type will only happen once, for the most part.
It lends itself to a table implementation. The type replaces the
many different methods of the meta class. The function object
creates a clear distinction between resolution and invocation.

Resolution...

----- 8< -----
Function function = metaClass.get(signature);
----- >8 -----

Invocation...

----- 8< -----
Object result = function.get(object, signature, parameters);
----- >8 -----

A very clear separation from resolution and invocation.

This initial switch on type kind of function is very common. So
common that it is implicit in the large function signature of
meta class. The one get method can be implemented as a table.

----- 8< -----
FunctionResolver[] resolvers = new FunctionResolvers[PROPERTY_GET];
SomewhereSomeoneWill.setResolvers(resolvers);
Object constructed = 
    resolvers[CONSTRUCTOR].getFunction(signature)
                          .call(object, signature, parameters);
----- >8 -----


Now, if I have a list, I can provide resolvers specificly for
property get and set.

Duck typing...

----- 8< -----
function swim(GroovyObject duck) {
    Signature[] signatures = getDuckType();
    if (duck.getMetaClass().quacksLike(signatures)) {
        addDuckToPond(duck);
    }
}
----- >8 -----

The signature, function, and resolver are all now atomic, and
can be stored in data structures, etc.

Out of range errors? Those are anywhere where you use a table.

> >The idea is that the MetaClass becomes a decision tree, and it is
> >extended through composition.

> Alan, I suppose we could implement Metaclasses like this but what  
> would the advantage be?

Composition.

----- 8< -----
// The basics.
FunctionReoslver resolver = CoreMethodResolver();

// Add collection specific methods like each.
resolver = new ColllectionsMethodResolver(resolver);

// Add property setting with maps.
resolver = new MapMethodResolver(resolver);

// Make this meta class behave like a map.
metaClass.set(INSTANCE_METHOD, resolver);
----- >8 -----

--
Alan Gutierrez - alan@engrm.com - http://engrm.com/blogometer/

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic