Costa Mirkin
Costa Mirkin

Reputation: 977

Add property from string to Groovy class

Is it possible to add property dynamically to Groovy class from string?
For example I ask user to insert string, say 'HelloString'
And I add property HelloString to existing Groovy glass?

Upvotes: 2

Views: 1391

Answers (2)

Jeff Scott Brown
Jeff Scott Brown

Reputation: 27255

If the property name and the property values are each dynamic, you can do something like this:

// these are hardcoded here but could be retrieved dynamically of course...
def dynamicPropertyName = 'someProperty'
def dynamicPropertyValue = 42

// adding the property to java.lang.String, but could be any class...
String.metaClass."${dynamicPropertyName}" =  dynamicPropertyValue


// now all instances of String have a property named "someProperty"
println 'jeff'.someProperty
println 'jeff'['someProperty']

Upvotes: 1

cfrick
cfrick

Reputation: 37073

There are several ways to deal with this. E.g. you can use propertyMissing

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"

assertEquals "bar", f.foo

For existing classes (any class) you can use ExpandoMetaClass

class Book {
  String title
}
Book.metaClass.getAuthor << {-> "Stephen King" }

def b = new Book("The Stand")

assert "Stephen King" == b.author

or by just using the Expando class:

def d = new Expando()
d."This is some very odd variable, but it works!" = 23
println d."This is some very odd variable, but it works!"

or @Delegate to a map as storage:

class C {
    @Delegate Map<String,Object> expandoStyle = [:]
}
def c = new C()
c."This also" = 42
println c."This also"

And this is how you set the property by a var:

def userInput = 'This is what the user said'
c."$userInput" = 666
println c."$userInput"

Upvotes: 5

Related Questions