Re: Small survey on the usage of the metaclass system and MOP
Jochen Theodorou <[email protected]>
| Newsgroups | gmane.comp.lang.groovy.user |
|---|---|
| Message-ID | <[email protected]> |
On 08.01.24 20:42, OCsite wrote:
[...]> - the extension class list is collected compile-time and (eventually
> when my build script creates the application) automatically added to the
> /org.codehaus.groovy.runtime.ExtensionModule/ manifest, so that they
> just-work without any extra ado.
So your variant is a clever way to use extension modules. You are not
using categories at all. That's good.
>> (2) per instance meta classes
>> https://groovy-lang.org/metaprogramming.html#_per_instance_metaclass
>> shows examples here
>> Anyone using that?
>
> Can't recall I ever needed that.
mocking and maybe some special kind of debugging are the only uses-cases
I found so far.
>> (3) Custom meta class
>> Anyway trying to force the usage of something else then MetaClassImpl
>> for the meta class?
>
> Well sort of, though a pretty trivial one. My goal is to get rid of
> NPEs; in my personal opinion that darned thing is a proper disaster and
> the right behaviour is a completely consistent /null/-propagation
> (essentially what Groovy calls a “safe dispatch”). Among many other
> things, what I do is
>
> ===
>
> def mc=new OCSNMC(org.codehaus.groovy.runtime.NullObject)
>
> mc.initialize()
>
> org.codehaus.groovy.runtime.NullObject.metaClass=mc
>
> ... ...
>
> }
>
> class OCSNMC extends DelegatingMetaClass {
>
> OCSNMC(Class clazz){
>
> super(clazz)
>
> }
>
> Object invokeMethod(Object object, String methodName, Object[]
> arguments) {
>
> if (arguments.size()==1 && methodName=='is') return arguments[0]==null
>
> if (arguments.size()==0 && methodName=='iterator') return [].iterator()
>
> if (arguments.size()==0 && methodName=='hasZeroValue') return YES
>
> null
>
> }
>
> // alas, does not seem to work for getProperty; that one must be
> supported by ASTTs
>
> }
>
> ===
>
> Aside that, not sure if interesting to you, but I install my own methods
> into metaclasses all the time, like e.g.,
>
> ===
>
> NSMutableDictionary.metaClass.putAt<<{ key,value ->
>
> if(value==nil) delegate.removeObjectForKey(key)
>
> else delegate.setObjectForKey(value,key)
>
> }
>
> ...
>
> NSKeyValueCoding.NullValue.class.metaClass.asBoolean={ -> false }
>
> ===
ok... but this is more a permanent thing. I am mostly interested in if
people want to change the meta class itself at a later point in time
instead of right from the beginning.
> and I even (of course having done /ExpandoMetaClass.enableGlobally()/)
> install global handlers
so your delegate is an ExpandoMC. Ok.
> ===
>
> // for some triple-weird reason simply defining propertyMissing in an
> extension does NOT work (never gets called)
>
> Object.metaClass.propertyMissing={name->
>
> DPA.propertyMissing(delegate,name)
>
> }
>
> Object.metaClass.static.propertyMissing={name->
>
> DPA.staticPropertyMissing(delegate,name)
>
> }
>
> ===
yeah... could be considered a bug I think.
> /DPA/ is my own rather non-trivial class, whose code dynamically fixes
> properties of library classes, i.e., allows me to write
> /SomeLibraryClassOrInstance.foo/ for classes which have either static or
> instance method /foo()/ and if so happens, /getFoo() { foo()
> }/ (essentially) is installed automatically to the metaclass (the
> rationale here is that the WebObjects standard, which long long predates
> the unlucky Java one, has setters /setFoo(foo)/ and getters /foo()/, not
> /getFoo()/).
So if we would go and say a class gets its meta class only once, but you
can control what it is if you must, then you have no problem... well
performance wise maybe
bye Jochen