|
View:
New views
11 Messages
—
Rating Filter:
Alert me
|
|
|
metaclass with enumHi,
Is it possible to use metaclass with enum ? I have : enum Ville // it's a "town". { TOKIO, MAKAO, OSLO, PARIS, NANTES, ZARASTAPARTAKIS } and : Ville.metaClass.parcouru = Integer.MAX_VALUE Ville.metaClass.précédent = 0 // Here I hope all town have parcouru MAX_VALUE and précédent 0. // So I try : Ville.PARIS.parcouru = 10 But... Exception in thread "main" groovy.lang.MissingPropertyException: No such property: parcouru for class: dijkstra.Ville at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:50) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setProperty(ScriptBytecodeAdapter.java:508) at Dijk.main(Dijk.groovy:32) I should want operate a single algorythme on Ville, and the properties "parcouru" and "précédent" (sorry for french) are only for this algorithme. Thanks. --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: metaclass with enumHi,
If you don't have to add enum properties parcouru and précédent dynamically at run-time, then you can do it like: ========================================================== enum Ville { TOKIO, MAKAO, OSLO, PARIS, NANTES, ZARASTAPARTAKIS Ville() { parcouru = Integer.MAX_VALUE précédent = 0 } Integer parcouru Integer précédent } println Ville.TOKIO.parcouru // is Integer.MAX_VALUE Ville.TOKIO.parcouru = 10 println Ville.TOKIO.parcouru // is now 10 println Ville.PARIS.parcouru // is still Integer.MAX_VALUE ========================================================== rgds, Roshan
On Fri, Nov 6, 2009 at 11:07 PM, Ista Pouss <istaous@...> wrote: Hi, |
|
|
Re: metaclass with enum2009/11/7 Roshan Dawrani <roshandawrani@...>:
> Hi, > If you don't have to add enum properties parcouru and précédent dynamically > at run-time, then you can do it like: > > ========================================================== > enum Ville > { > TOKIO, MAKAO, OSLO, PARIS, NANTES, ZARASTAPARTAKIS > Ville() { > parcouru = Integer.MAX_VALUE > précédent = 0 > } > Integer parcouru > Integer précédent > } Yes, but these properties are not "ville" (ie: town)'s properties. It's properties for the algorithm. In java, I make something like that in this case : class AlgoTown // stupid name, sorry { Ville ville; // it's the town int parcouru; int précédent; } With groovy (i'm a neewbee), my impression is : it is possible to add properties at runtime with metaclass (and expando ? ) thing. Is it a rigth / good impression ? Is it The Good Thing To Do in my case ? Is it possible with "enum" ? How ? --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: metaclass with enumIn the first mail you wanted to access Ville.PARIS.parcouru, which meant that you wanted to have "parcouru" on the enum constant, which was of type Ville.
If you want to add property "parcouru" at runtime on some regular class, then you can very easily do it. Code below shows 2 ways of doing it: ======================================================= enum Ville {TOKIO, PARIS} class AlgoTown { Ville ville; } String runtimePropName = "précédent" addPropertyWhoseNameIsKnown() addPropertyWhoseNameIsNotKnownUntilRuntime(runtimePropName) def addPropertyWhoseNameIsKnown() { AlgoTown.metaClass.parcouru = Integer.MAX_VALUE } def addPropertyWhoseNameIsNotKnownUntilRuntime(propName) { AlgoTown.metaClass."$propName" = 0 } def algo1 = new AlgoTown() def algo2 = new AlgoTown() println algo1.parcouru // Integer.MAX_VALUE println algo1."$runtimePropName" // 0 algo1.parcouru = 10 // change algo1's parcouru property to 10 println algo1.parcouru // 10 println algo2.parcouru // algo2 still has parcouru = Integer.MAX_VALUE ======================================================= Hope it helps. Roshan On Sat, Nov 7, 2009 at 12:49 PM, Ista Pouss <istaous@...> wrote: 2009/11/7 Roshan Dawrani <roshandawrani@...>: |
|
|
Re: metaclass with enumYes, but how do that on the enum itself ?
As an exemple, I do this code in the groovy web console : class A {} enum Ville {TOKIO, PARIS} assert Ville.TOKIO instanceof Ville // of course. A.metaClass.cool = 10 a = new A() assert a.cool == 10 Ville.metaClass.cool = 10 assert Ville.TOKIO.cool == 10 // BING ! I do exactly the same metaClass thing, on a "regular" class (A), and on an enum (Ville). It's OK for instance class A (a), not for instance Ville (TOKIO). The error in groovy web console (http://groovyconsole.appspot.com/) is : groovy.lang.MissingPropertyException: No such property: cool for class: Ville at Script1.run(Script1.groovy:12) 2009/11/7 Roshan Dawrani <roshandawrani@...>: > In the first mail you wanted to access Ville.PARIS.parcouru, which meant > that you wanted to have "parcouru" on the enum constant, which was of type > Ville. > > If you want to add property "parcouru" at runtime on some regular class, > then you can very easily do it. Code below shows 2 ways of doing it: > ======================================================= > enum Ville {TOKIO, PARIS} > class AlgoTown > { > Ville ville; > } > > String runtimePropName = "précédent" > addPropertyWhoseNameIsKnown() > addPropertyWhoseNameIsNotKnownUntilRuntime(runtimePropName) > > def addPropertyWhoseNameIsKnown() { > AlgoTown.metaClass.parcouru = Integer.MAX_VALUE > } > def addPropertyWhoseNameIsNotKnownUntilRuntime(propName) { > AlgoTown.metaClass."$propName" = 0 > } > > def algo1 = new AlgoTown() > def algo2 = new AlgoTown() > > println algo1.parcouru // Integer.MAX_VALUE > println algo1."$runtimePropName" // 0 > > algo1.parcouru = 10 // change algo1's parcouru property to 10 > > println algo1.parcouru // 10 > println algo2.parcouru // algo2 still has parcouru = Integer.MAX_VALUE > ======================================================= > > Hope it helps. > Roshan > > > On Sat, Nov 7, 2009 at 12:49 PM, Ista Pouss <istaous@...> wrote: >> >> 2009/11/7 Roshan Dawrani <roshandawrani@...>: >> > Hi, >> > If you don't have to add enum properties parcouru and précédent >> > dynamically >> > at run-time, then you can do it like: >> > >> > ========================================================== >> > enum Ville >> > { >> > TOKIO, MAKAO, OSLO, PARIS, NANTES, ZARASTAPARTAKIS >> > Ville() { >> > parcouru = Integer.MAX_VALUE >> > précédent = 0 >> > } >> > Integer parcouru >> > Integer précédent >> > } >> >> Yes, but these properties are not "ville" (ie: town)'s properties. >> It's properties for the algorithm. >> >> In java, I make something like that in this case : >> >> class AlgoTown // stupid name, sorry >> { >> Ville ville; // it's the town >> int parcouru; >> int précédent; >> } >> >> With groovy (i'm a neewbee), my impression is : it is possible to add >> properties at runtime with metaclass (and expando ? ) thing. Is it a >> rigth / good impression ? Is it The Good Thing To Do in my case ? Is >> it possible with "enum" ? How ? >> >> --------------------------------------------------------------------- >> To unsubscribe from this list, please visit: >> >> http://xircles.codehaus.org/manage_email >> >> > > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: metaclass with enumOk, now I get the question fully.
You want to define new properties on the enum but not from inside the enum as I first suggested but at runtime. I don't know at the moment a good, clean answer to that question - because enums are a little special and their instance are created internally when enum class is loaded, so the changes that you make to enum's metaclass after the enum is fully loaded (and its instances are constructed) are not seen by the enum instances like TOKIO. Till any better answer comes along, one possible solution is below. ================================= enum Ville { TOKIO, PARIS } // after this already constructed enum instances still pick up enum class level metaclass changes made at runtime ExpandoMetaClass.enableGlobally() Ville.metaClass.cool = 10 println Ville.PARIS.cool // after this enum instance will go back to its own MC again and not see enum class level metaclass changes made at runtime ExpandoMetaClass.disbleGlobally() println Ville.PARIS.cool // will fail again ================================= -- Roshan On Sat, Nov 7, 2009 at 2:06 PM, Ista Pouss <istaous@...> wrote: Yes, but how do that on the enum itself ? |
|
|
Re: metaclass with enumHere is another solution, which changes the metaClass of enum instances at runtime without needing to do a global change by calling EMC.enableGlobally() :-
================================================ enum Ville { TOKIO, PARIS def metaClass MetaClass getMetaClass() { if(!metaClass) { metaClass = new ExpandoMetaClass(Ville, true, true); metaClass.initialize() } metaClass } def addProperty(propName, propValue) { metaClass = new ExpandoMetaClass(Ville, true, true); this.metaClass."$propName" = propValue metaClass.initialize(); } } // make the metaclass changes on the enum instances Ville.values().each { enumInstance -> enumInstance.addProperty('parcouru', Integer.MAX_VALUE) enumInstance.addProperty('précédent', 0) } // check if the enum has now got the new Properties assert Ville.TOKIO.parcouru == Integer.MAX_VALUE assert Ville.TOKIO.précédent == 0 // change runtime properties and check on different instances Ville.TOKIO.parcouru = 10 assert Ville.TOKIO.parcouru == 10 assert Ville.PARIS.parcouru == Integer.MAX_VALUE println "Done" ======================================= Hope it helps. Roshan On Sat, Nov 7, 2009 at 2:26 PM, Roshan Dawrani <roshandawrani@...> wrote: Ok, now I get the question fully. |
|
|
Re: metaclass with enumSlightly improved version of the last solution (removes the enum's metaClass field and getMetaClass() method). Sorry for so many versions. I am trying metaclass changes on enums for the first time.
======================================== enum Ville { TOKIO, PARIS def addProperties(propMap) { def emc = new ExpandoMetaClass(Ville, true, true); setMetaClass(emc) def itr = propMap.keySet().iterator() while(itr.hasNext()) { def propName = itr.next() this.metaClass."$propName" = propMap[propName] } emc.initialize(); } } Ville.values().each { enumInstance -> enumInstance.addProperties([parcouru:Integer.MAX_VALUE, précédent:0]) } assert Ville.TOKIO.parcouru == Integer.MAX_VALUE assert Ville.TOKIO.précédent == 0 Ville.TOKIO.parcouru = 10 assert Ville.TOKIO.parcouru == 10 assert Ville.PARIS.parcouru == Integer.MAX_VALUE println "Done" ======================================== On Sat, Nov 7, 2009 at 2:52 PM, Roshan Dawrani <roshandawrani@...> wrote: Here is another solution, which changes the metaClass of enum instances at runtime without needing to do a global change by calling EMC.enableGlobally() :- |
|
|
Re: metaclass with enumShamelessly mailing one more version. The last one!
=================================================== enum Ville { TOKIO, PARIS } Ville.metaClass.parcouru = Integer.MAX_VALUE Ville.metaClass.précédent = 0 // refresh metaclass of each instance with the latest class level metaclass Ville.values().each {enumInstance -> enumInstance.metaClass = null } assert Ville.TOKIO.parcouru == Integer.MAX_VALUE assert Ville.TOKIO.précédent == 0 Ville.TOKIO.parcouru = 10 assert Ville.TOKIO.parcouru == 10 assert Ville.PARIS.parcouru == Integer.MAX_VALUE println "Done" =================================================== rgds, Roshan On Sat, Nov 7, 2009 at 3:15 PM, Roshan Dawrani <roshandawrani@...> wrote: Slightly improved version of the last solution (removes the enum's metaClass field and getMetaClass() method). Sorry for so many versions. I am trying metaclass changes on enums for the first time. |
|
|
Re: metaclass with enumOK.
I understand the expert point of view but, from a newbee point of view, it's a curious feature ! Planty of thanks, I go on with groovy. 2009/11/7 Roshan Dawrani <roshandawrani@...>: > Shamelessly mailing one more version. The last one! > > =================================================== > enum Ville > { > TOKIO, PARIS > } > > Ville.metaClass.parcouru = Integer.MAX_VALUE > Ville.metaClass.précédent = 0 > > // refresh metaclass of each instance with the latest class level metaclass > Ville.values().each {enumInstance -> > enumInstance.metaClass = null > } > > assert Ville.TOKIO.parcouru == Integer.MAX_VALUE > assert Ville.TOKIO.précédent == 0 > > Ville.TOKIO.parcouru = 10 > assert Ville.TOKIO.parcouru == 10 > assert Ville.PARIS.parcouru == Integer.MAX_VALUE > > println "Done" > =================================================== > > rgds, > Roshan > > On Sat, Nov 7, 2009 at 3:15 PM, Roshan Dawrani <roshandawrani@...> > wrote: >> >> Slightly improved version of the last solution (removes the enum's >> metaClass field and getMetaClass() method). Sorry for so many versions. I am >> trying metaclass changes on enums for the first time. >> >> ======================================== >> enum Ville >> { >> TOKIO, PARIS >> >> def addProperties(propMap) { >> def emc = new ExpandoMetaClass(Ville, true, true); >> setMetaClass(emc) >> def itr = propMap.keySet().iterator() >> while(itr.hasNext()) { >> def propName = itr.next() >> this.metaClass."$propName" = propMap[propName] >> } >> emc.initialize(); >> } >> } >> >> Ville.values().each { enumInstance -> >> enumInstance.addProperties([parcouru:Integer.MAX_VALUE, précédent:0]) >> } >> >> assert Ville.TOKIO.parcouru == Integer.MAX_VALUE >> assert Ville.TOKIO.précédent == 0 >> >> Ville.TOKIO.parcouru = 10 >> assert Ville.TOKIO.parcouru == 10 >> assert Ville.PARIS.parcouru == Integer.MAX_VALUE >> println "Done" >> ======================================== >> >> On Sat, Nov 7, 2009 at 2:52 PM, Roshan Dawrani >> <roshandawrani@...> wrote: >>> >>> Here is another solution, which changes the metaClass of enum instances >>> at runtime without needing to do a global change by calling >>> EMC.enableGlobally() :- >>> >>> ================================================ >>> enum Ville >>> { >>> TOKIO, PARIS >>> def metaClass >>> MetaClass getMetaClass() { >>> if(!metaClass) { >>> metaClass = new ExpandoMetaClass(Ville, true, true); >>> metaClass.initialize() >>> } >>> metaClass >>> } >>> def addProperty(propName, propValue) { >>> metaClass = new ExpandoMetaClass(Ville, true, true); >>> this.metaClass."$propName" = propValue >>> metaClass.initialize(); >>> } >>> } >>> >>> // make the metaclass changes on the enum instances >>> Ville.values().each { enumInstance -> >>> enumInstance.addProperty('parcouru', Integer.MAX_VALUE) >>> enumInstance.addProperty('précédent', 0) >>> } >>> >>> // check if the enum has now got the new Properties >>> assert Ville.TOKIO.parcouru == Integer.MAX_VALUE >>> assert Ville.TOKIO.précédent == 0 >>> >>> // change runtime properties and check on different instances >>> Ville.TOKIO.parcouru = 10 >>> assert Ville.TOKIO.parcouru == 10 >>> assert Ville.PARIS.parcouru == Integer.MAX_VALUE >>> println "Done" >>> ======================================= >>> >>> Hope it helps. >>> Roshan >>> >>> On Sat, Nov 7, 2009 at 2:26 PM, Roshan Dawrani >>> <roshandawrani@...> wrote: >>>> >>>> Ok, now I get the question fully. >>>> >>>> You want to define new properties on the enum but not from inside the >>>> enum as I first suggested but at runtime. >>>> >>>> I don't know at the moment a good, clean answer to that question - >>>> because enums are a little special and their instance are created internally >>>> when enum class is loaded, so the changes that you make to enum's metaclass >>>> after the enum is fully loaded (and its instances are constructed) are not >>>> seen by the enum instances like TOKIO. >>>> >>>> Till any better answer comes along, one possible solution is below. >>>> >>>> ================================= >>>> enum Ville >>>> { >>>> TOKIO, PARIS >>>> } >>>> // after this already constructed enum instances still pick up enum >>>> class level metaclass changes made at runtime >>>> ExpandoMetaClass.enableGlobally() >>>> >>>> Ville.metaClass.cool = 10 >>>> >>>> println Ville.PARIS.cool >>>> >>>> // after this enum instance will go back to its own MC again and not see >>>> enum class level metaclass changes made at runtime >>>> ExpandoMetaClass.disbleGlobally() >>>> >>>> println Ville.PARIS.cool // will fail again >>>> ================================= >>>> >>>> -- Roshan >>>> >>>> On Sat, Nov 7, 2009 at 2:06 PM, Ista Pouss <istaous@...> wrote: >>>>> >>>>> Yes, but how do that on the enum itself ? >>>>> >>>>> As an exemple, I do this code in the groovy web console : >>>>> >>>>> class A {} >>>>> enum Ville {TOKIO, PARIS} >>>>> >>>>> assert Ville.TOKIO instanceof Ville // of course. >>>>> >>>>> A.metaClass.cool = 10 >>>>> >>>>> a = new A() >>>>> assert a.cool == 10 >>>>> >>>>> Ville.metaClass.cool = 10 >>>>> assert Ville.TOKIO.cool == 10 // BING ! >>>>> >>>>> I do exactly the same metaClass thing, on a "regular" class (A), and >>>>> on an enum (Ville). It's OK for instance class A (a), not for instance >>>>> Ville (TOKIO). >>>>> >>>>> The error in groovy web console (http://groovyconsole.appspot.com/) is >>>>> : >>>>> >>>>> groovy.lang.MissingPropertyException: No such property: cool for class: >>>>> Ville >>>>> at Script1.run(Script1.groovy:12) >>>>> >>>>> >>>>> >>>>> 2009/11/7 Roshan Dawrani <roshandawrani@...>: >>>>> > In the first mail you wanted to access Ville.PARIS.parcouru, which >>>>> > meant >>>>> > that you wanted to have "parcouru" on the enum constant, which was of >>>>> > type >>>>> > Ville. >>>>> > >>>>> > If you want to add property "parcouru" at runtime on some regular >>>>> > class, >>>>> > then you can very easily do it. Code below shows 2 ways of doing it: >>>>> > ======================================================= >>>>> > enum Ville {TOKIO, PARIS} >>>>> > class AlgoTown >>>>> > { >>>>> > Ville ville; >>>>> > } >>>>> > >>>>> > String runtimePropName = "précédent" >>>>> > addPropertyWhoseNameIsKnown() >>>>> > addPropertyWhoseNameIsNotKnownUntilRuntime(runtimePropName) >>>>> > >>>>> > def addPropertyWhoseNameIsKnown() { >>>>> > AlgoTown.metaClass.parcouru = Integer.MAX_VALUE >>>>> > } >>>>> > def addPropertyWhoseNameIsNotKnownUntilRuntime(propName) { >>>>> > AlgoTown.metaClass."$propName" = 0 >>>>> > } >>>>> > >>>>> > def algo1 = new AlgoTown() >>>>> > def algo2 = new AlgoTown() >>>>> > >>>>> > println algo1.parcouru // Integer.MAX_VALUE >>>>> > println algo1."$runtimePropName" // 0 >>>>> > >>>>> > algo1.parcouru = 10 // change algo1's parcouru property to 10 >>>>> > >>>>> > println algo1.parcouru // 10 >>>>> > println algo2.parcouru // algo2 still has parcouru = >>>>> > Integer.MAX_VALUE >>>>> > ======================================================= >>>>> > >>>>> > Hope it helps. >>>>> > Roshan >>>>> > >>>>> > >>>>> > On Sat, Nov 7, 2009 at 12:49 PM, Ista Pouss <istaous@...> >>>>> > wrote: >>>>> >> >>>>> >> 2009/11/7 Roshan Dawrani <roshandawrani@...>: >>>>> >> > Hi, >>>>> >> > If you don't have to add enum properties parcouru and précédent >>>>> >> > dynamically >>>>> >> > at run-time, then you can do it like: >>>>> >> > >>>>> >> > ========================================================== >>>>> >> > enum Ville >>>>> >> > { >>>>> >> > TOKIO, MAKAO, OSLO, PARIS, NANTES, ZARASTAPARTAKIS >>>>> >> > Ville() { >>>>> >> > parcouru = Integer.MAX_VALUE >>>>> >> > précédent = 0 >>>>> >> > } >>>>> >> > Integer parcouru >>>>> >> > Integer précédent >>>>> >> > } >>>>> >> >>>>> >> Yes, but these properties are not "ville" (ie: town)'s properties. >>>>> >> It's properties for the algorithm. >>>>> >> >>>>> >> In java, I make something like that in this case : >>>>> >> >>>>> >> class AlgoTown // stupid name, sorry >>>>> >> { >>>>> >> Ville ville; // it's the town >>>>> >> int parcouru; >>>>> >> int précédent; >>>>> >> } >>>>> >> >>>>> >> With groovy (i'm a neewbee), my impression is : it is possible to >>>>> >> add >>>>> >> properties at runtime with metaclass (and expando ? ) thing. Is it a >>>>> >> rigth / good impression ? Is it The Good Thing To Do in my case ? Is >>>>> >> it possible with "enum" ? How ? >>>>> >> >>>>> >> >>>>> >> --------------------------------------------------------------------- >>>>> >> To unsubscribe from this list, please visit: >>>>> >> >>>>> >> http://xircles.codehaus.org/manage_email >>>>> >> >>>>> >> >>>>> > >>>>> > >>>>> >>>>> --------------------------------------------------------------------- >>>>> To unsubscribe from this list, please visit: >>>>> >>>>> http://xircles.codehaus.org/manage_email >>>>> >>>>> >>>> >>> >> > > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: metaclass with enumGood to hear that. I get my time's worth, if you are continuing to go on with groovy. :-)
Have fun. Roshan On Mon, Nov 9, 2009 at 12:12 PM, Ista Pouss <istaous@...> wrote: OK. |
| Free embeddable forum powered by Nabble | Forum Help |