If you want to avoid the use of ExpandoMetaClass and that you potentially want to have this behavior on multiple classes, you can now rely on the traits for this. I had written this in a presentation about traits for S2GX last year:

|trait ExpandoTrait {||
||    private final Map<String,?> values = [:]||
||    def propertyMissing(String name) { values.get(name) }||
||    void setProperty(String name, value) {||
||        println "Setting dynamic property $name"||
||        values.put(name, value)||
||    }||
||}||
||class Person implements ExpandoTrait {||
||    String name||
||}||
||def p = new Person(name: 'Cedric')||
||assert p.name == 'Cedric'||
||p.age = 35||
||assert p.age == 35|

Best regards,


\On 05/26/2015 11:02 PM, Schalk Cronjé wrote:
I did at one stage, and the result is the same. The only way I could get it to work is something like

class A {
  private Expando props = new Expando()

  void addSomeProp( String name, String key, def value) {
    def p = props.getProperty(name)
    if (null = p) {
      props.setProperty( name,[:] )
    }
    props."${name}"[key]=value.toString()
  }

  def missingProperty( String name ) {
    def p = props.getProperty(name)
    if( null = p ) {
      throw new MissingPropertyException( name,this.class )
    }
    return p
  }
}

Which is strange, as it is what I think ExpandoMetaClass would do anyway.

On 26/05/2015 19:33, KARR, DAVID wrote:
-----Original Message-----
From: Schalk Cronjé [mailto:[email protected]]
Sent: Tuesday, May 26, 2015 8:21 AM
To: [email protected]
Subject: Dynamic adding properties to class

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()
    }
}
Perhaps try "metaClass.hasProperty(name)" instead?

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.

--
Schalk W. Cronjé
Twitter / Ello / Toeter : @ysb33r




--
Cédric Champeau
Groovy language developer
http://twitter.com/CedricChampeau
http://melix.github.io/blog

Reply via email to