Expando

The Expando is not a collection in the strictest sense, but in some ways it is similar to a Map, or objects in JavaScript that do not have to have their properties defined in advance. It allows you to create dynamic objects by making use of Groovy's closure mechanisms. An Expando is different from a map in that you can provide synthetic methods that you can call on the object.

~/Lgroovy/collections$ cat -n expando1.groovy 
     1  def player = new Expando()
     2  player.name = "Dierk"
     3  player.greeting = { "Hello, my name is $name" }
     4  
     5  println player.greeting()
     6  player.name = "Jochen"
     7  println player.greeting()
     8  
~/Lgroovy/collections$ groovy expando1.groovy 
Hello, my name is Dierk
Hello, my name is Jochen

The player.greeting assignment passes in a closure to execute when greeting() is called on the Expando. Notice that the closure has access to the properties assigned to the Expando, even though these values may change over time, using Groovy's GString "$variableOrProperty" notation.

Sigue otro ejemplo que muestra diferencias de conducta entre un Map y un Expando:

~/Lgroovy/objects$ cat -n expando.groovy 
     1  def map_boy = [age: 6, doSomething: { println 'pick nose'}, toString: {'hi'}]  
     2  def exp_boy = new Expando(age: 6, doSomething: { println 'pick nose' }, toString:{'hi'} )  
     3     
     4  def boys = [map_boy, exp_boy]  
     5     
     6  boys.each{boy->  
     7    println boy.age  
     8    boy.doSomething()  
     9    println boy.toString()  
    10  }      
~/Lgroovy/objects$ groovy expando.groovy 
6
pick nose
[age:6, doSomething:expando$_run_closure1@6d732ed2, toString:expando$_run_closure2@25071521]
6
pick nose
hi
Véase la cuestión Still fuzzy on the Expando class - have any good examples of its use? en coderanch:
Both map andExpando allowed me to mock out properties and closures. The closures let me make calls on the map orExpando as if I were calling a normal method.

The difference was on toString and my hunch is that equals and hashCode work the same way -Expando lets us essentially override them while map does not.

If this truly is the only difference, I think I'd rather stick to using maps unless I absolutely need to use toString, hashCode, or equals.

Casiano Rodríguez León
2010-04-30