Search code examples
groovygroovyshell

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?


Solution

  • 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"