Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy dynamic property per object

Using Groovy 1.8. I'm trying to create a dynamic class definition that will cache properties per object. I did use propertyMissing without adding the property to the object just fine. I just think caching the properties would be more efficient. Right?

Note that each instance must have its own different properties.

The code below works fine:

class C {}
def c = new C()
c.metaClass.prop = "a C property"
println c.prop

def x = new C()
x.prop

will output:

a C property
groovy.lang.MissingPropertyException: No such property: prop for class: C

If I need to this problematically:

class A {
    def propertyMissing(String name) {
        if(!this.hasProperty(name)) {
            println "create new propery $name"
            this.metaClass."$name" = "Dyna prop $name"
            println "created new propery $name"
        }
        this.metaClass."$name"
    }
}

a = new A()
println a.p1

For A, I get as far as "create new property", but the line this.metaClass."$name" = "Dyna prop $name" fails with: No such property: p1 for class at line 5

Whats wrong?

like image 247
Ayman Avatar asked Jul 04 '11 07:07

Ayman


Video Answer


2 Answers

This code should do what you want:

class A {
  A() {
    def mc = new ExpandoMetaClass( A, false, true)
    mc.initialize()
    this.metaClass = mc
  }

  def propertyMissing( String name ) {
    println "create new propery $name"
    def result = "Dyna prop $name"
    this.metaClass."$name" = result
    println "created new propery $name"
    result
  }
}

a = new A()
println a.p1
println a.p1

That outputs:

create new propery p1
created new propery p1
Dyna prop p1
Dyna prop p1
like image 96
tim_yates Avatar answered Nov 09 '22 14:11

tim_yates


Why don't you store your dynamic properties in a simple HashMap?

class Foo {
    def storage = [:]
    def propertyMissing(String name, value) { storage[name] = value }
    def propertyMissing(String name) { storage[name] }
}
def f = new Foo()
f.foo = "bar"

This is the standard example from: http://groovy.codehaus.org/Using+methodMissing+and+propertyMissing

Note, you don't have to check if the property is really missing ... if it won't be missing, the method would not be called in the first place.

like image 33
Angel O'Sphere Avatar answered Nov 09 '22 13:11

Angel O'Sphere