Jochen, > On 8. 1. 2024, at 22:12, Jochen Theodorou <blackd...@gmx.org> wrote: ... ... ... > 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
Precisely. Thanks a lot! OC > On 8. 1. 2024, at 22:12, Jochen Theodorou <blackd...@gmx.org> wrote: > > 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 > >