Re: Small survey on the usage of the metaclass system and MOP
On 09.01.24 22:53, MG wrote: Hi Jochen, we do not use any of these Groovy features - why is that information relevant to you ? I was playing around with some thoughts for me the biggest problem are per instance meta classes really. If you are gauging if you can remove some potentially unused features from Groovy, it might be best to state so - nothing to get people to take the time to reply, than to tell them an important feature of their language might be cut (or trimmed)... ;-) Well, if I would make a suggestion to remove these or one of them, it would have to be based on practical data. That is how the user is using it, how it is understood, performance, maintainability and correctness. Both features do not impose a big burden on method calls actually, so performance is maybe not a problem. But we have to maintain a complicated datastructure with possible memory leaks if you use per instance meta classes on java classes. The usage is low and I am not sure how many people realize the implications of using them. bye Jochen
Re: Small survey on the usage of the metaclass system and MOP
Hi Jochen, we do not use any of these Groovy features - why is that information relevant to you ? If you are gauging if you can remove some potentially unused features from Groovy, it might be best to state so - nothing to get people to take the time to reply, than to tell them an important feature of their language might be cut (or trimmed)... ;-) Cheers, mg On 08/01/2024 16:10, Jochen Theodorou wrote: Hi all, I would like to know from users on this list mostly if they are using specific features of the meta class system and MOP, but especially what for. (1) categories https://blog.mrhaki.com/2009/09/groovy-goodness-use-categories-to-add.html shows an example. Basically you have use (CategoryClass) { // some code and callstack here influenced by CategoryClass } I am especially interested in knowing if you try to add a method to code that is not part if the use-block here. (2) per instance meta classes https://groovy-lang.org/metaprogramming.html#_per_instance_metaclass shows examples here Anyone using that? (3) Custom meta class Anyway trying to force the usage of something else then MetaClassImpl for the meta class? If you do not understand the question at all, then the answer would be no. bye Jochen
Re: Small survey on the usage of the metaclass system and MOP
Jochen, > On 8. 1. 2024, at 22:12, Jochen Theodorou 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 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 > >
Re: Small survey on the usage of the metaclass system and MOP
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
Re: Small survey on the usage of the metaclass system and MOP
Jochen, > On 8. 1. 2024, at 16:10, Jochen Theodorou wrote: > I would like to know from users on this list mostly if they are using > specific features of the meta class system and MOP, but especially what for. > > (1) categories > ... > use (CategoryClass) { > // some code and callstack here influenced by CategoryClass > } > I am especially interested in knowing if you try to add a method to code that > is not part if the use-block here. All the time, mostly to extend library classes, occasionally to split my own class implementation to more source files. I never ever use the use-block. My aim here is to have something as close to the Objective-C categories as possible. Not entirely successful (the worst problem is that the Groovy category-based extensions do not work properly through introspection, whilst methods added by an ObjC category are real first-class citizens, not distinguishable from the “normal” ones), but I am reasonably close and the support is immensely useable to me. For convenience, I did my own Extension ASTT closely based on the Alex Tkachman's Category, but improved a bit, so that - inside of my @Extension(String) class MyStringExtensions { ... }, I can put both instance and static extension methods, and for the latter, my ASTT automatically creates an appropriate static extension class; - 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. > (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. > (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 } === and I even (of course having done ExpandoMetaClass.enableGlobally()) install global handlers === // 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) } === 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()). Thanks and all the best, OC
Re: Small survey on the usage of the metaclass system and MOP
I myself use @POJO almost everywhere. On Mon, Jan 8, 2024, 09:11 Jochen Theodorou wrote: > Hi all, > > I would like to know from users on this list mostly if they are using > specific features of the meta class system and MOP, but especially what > for. > > > (1) categories > > https://blog.mrhaki.com/2009/09/groovy-goodness-use-categories-to-add.html > shows an example. Basically you have > > use (CategoryClass) { >// some code and callstack here influenced by CategoryClass > } > > I am especially interested in knowing if you try to add a method to code > that is not part if the use-block here. > > > (2) per instance meta classes > > https://groovy-lang.org/metaprogramming.html#_per_instance_metaclass > shows examples here > > Anyone using that? > > (3) Custom meta class > > Anyway trying to force the usage of something else then MetaClassImpl > for the meta class? If you do not understand the question at all, then > the answer would be no. > > > bye Jochen >