• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Still fuzzy on the Expando class - have any good examples of its use?

 
Chris Patti
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've gone over the section in Groovy in Action a number of times and I am still having a hard time wrapping my head around the Expando class.

It might help to have an example of somewhere it's used - e.g. what kinds of problems is Expando good at solving?

Thanks in advance!
-Chris
 
Marc Peabody
pie sneak
Sheriff
Posts: 4727
Mac Ruby VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've used maps a bit in Groovy when I need to mock something in a unit test like explained here:
Developer Testing using Maps and Expandos instead of Mocks

I also sometimes like to swap out a closure in a class for another closure when I test. It's been so helpful that sometimes I wonder about just replacing all of my methods with closures.


Since Expando and map have so much in common, I wrote some code to see how the two might behave differently. (Go ahead and drop this in your GroovyConsole)


The result:
6
pick nose
{age=6, doSomething=Script7$_run_closure1@b6f7f5, toString=Script7$_run_closure2@5113f0}
6
pick nose
hi

Both map and Expando allowed me to mock out properties and closures. The closures let me make calls on the map or Expando 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.
 
Chris Patti
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Marc Peabody:
I've used maps a bit in Groovy when I need to mock something in a unit test like explained here:
Developer Testing using Maps and Expandos instead of Mocks

I also sometimes like to swap out a closure in a class for another closure when I test. It's been so helpful that sometimes I wonder about just replacing all of my methods with closures.


Since Expando and map have so much in common, I wrote some code to see how the two might behave differently. (Go ahead and drop this in your GroovyConsole)


The result:
6
pick nose
{age=6, doSomething=Script7$_run_closure1@b6f7f5, toString=Script7$_run_closure2@5113f0}
6
pick nose
hi

Both map and Expando allowed me to mock out properties and closures. The closures let me make calls on the map or Expando 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.


Aha! I finally get it! So an Expando is just a map that lets you call methods on it which are actually the map's keys, and the values are a closure that does whatever you want it to do.

I rather wish the book had stated this in plain language, it made an analogy to a bean with expanded functionality which is true but doesn't explain what's happening very clearly.

Thanks a bunch!
 
Marc Peabody
pie sneak
Sheriff
Posts: 4727
Mac Ruby VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Chris Patti:
Aha! I finally get it! So an Expando is just a map that lets you call methods on it which are actually the map's keys, and the values are a closure that does whatever you want it to do.

Just to make sure you caught it, a map in Groovy lets you use keys as methods (syntactically) too. See the doSomething key in my example, which worked for both map and Expando.

The primary difference was for toString, hashCode, and equals - the map won't let you override them but Expando does.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic