groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jochen Theodorou <blackd...@gmx.org>
Subject Re: Dynamic adding properties to class
Date Wed, 27 May 2015 07:43:29 GMT
Am 26.05.2015 17:20, schrieb Schalk Cronjé:
> This should be straight-forward, but it is failing for me (at least on
> 2.3x and 2.4.x). What am I doing wrong?
>
> Here is some code sufficiently distilled.
>
> class A {
>    void addSomeProp( String name,String key, def value ) {
>      if(metaClass.getMetaProperty(name)==null) {
>        metaClass."${name}" = [:]
>      }
>      metaClass."${name}"[key]=value.toString()
>    }
> }
>
> A a = new A()
> a.addSomeProp( 'info','version',3)  // Fails with: No such property:
> info for class: groovy.lang.MetaClassImpl
>
> The idea is to add a map (of name) if it does not exist, and then add
> items into the map.


What you want to do requires ExpandoMetaClass, which is not the default, 
unless you do ExpandoMetaClass.enableGlobally().

something like

A a = new A()
def mc = new ExpandoMetaClass(A,true,true)
mc.initialize()
a.metaClass = mc

can be used as alternative.

Then, there is also a bug in 
`metaClass."${name}"[key]=value.toString()`. since you want to set the 
value of the property you don't operate on the metaClass, where you 
defined the property, instead you work on the instance of the class:

this."${name}"[key]=value.toString()

complete program:

class A {
   void addSomeProp( String name,String key, def value ) {
     if(metaClass.getMetaProperty(name)==null) {
       metaClass."${name}" = [:]
     }
     this."${name}"[key]=value.toString()
   }
}

A a = new A()
def mc = new ExpandoMetaClass(A,true,true)
mc.initialize()
a.metaClass = mc
a.addSomeProp( 'info','version',3)
assert a.info.version == '3'

bye blackdrag

-- 
Jochen "blackdrag" Theodorou
blog: http://blackdragsview.blogspot.com/


Mime
View raw message