groovy metaprogramming for dummies
TRANSCRIPT
![Page 1: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/1.jpg)
Groovy Metaprogramming
for Dummies
Darren Cruse
(not a professional speaker: please no heckling or throwing of food per Groovy User Group Regulation 103a subsection e)
Monday, June 7, 2010
![Page 2: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/2.jpg)
Meta Stuff(about the meta talk)
•Who am I?Once too good for “scripting”
Former Perl Nut
Recent Javascript Graduate
Improving Groovy Skills
Monday, June 7, 2010
![Page 3: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/3.jpg)
Meta Stuff(about the meta talk)
•What’s this talk about?metaprogramming = “programming the program”
metaprogramming = what makes groovy really groovy!
Monday, June 7, 2010
![Page 4: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/4.jpg)
Meta Stuff(about the meta talk)
• Who’s this talk for?
Ideally: Someone who’s seen a bit of groovy and aspires to get to the next level
Someone still unconvinced groovy’s power and productivity is sufficiently greater than java’s to merit learning a language with such a silly name.
(and you advanced guys feel free to dive in and help me out!)
Monday, June 7, 2010
![Page 5: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/5.jpg)
Builders = Metaprogramming Magic
def builder = new StreamingMarkupBuilder()builder.encoding = 'UTF-8'def books = builder.bind { mkp.xmlDeclaration() namespaces << [meta:'http://meta/book/info'] books(count: 3) { book(id: 1) { title lang:'en', 'Groovy in Action' meta.isbn '1-932394-84-2' } book(id: 2) { title lang:'en', 'Groovy Programming' meta.isbn '0123725070' } book(id: 3) { title 'Groovy & Grails' comment << 'Not yet available.' } book(id: 4) { mkp.yieldUnescaped '<title>Griffon Guide</title>' } }}
Monday, June 7, 2010
![Page 6: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/6.jpg)
Builders = Metaprogramming Magic
<?xml version="1.0" encoding="UTF-8"?><books xmlns:meta="http://meta/book/info" count="3"> <book id="1"> <title lang="en">Groovy in Action</title> <meta:isbn>1-932394-84-2</meta:isbn> </book> <book id="2"> <title lang="en">Groovy Programming</title> <meta:isbn>0123725070</meta:isbn> </book> <book id="3"> <title>Groovy & Grails</title> <!--Not yet available.--> </book> <book id="4"> <title>Griffon Guide</title> </book></books>
Monday, June 7, 2010
![Page 7: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/7.jpg)
def builder = new StreamingMarkupBuilder()builder.encoding = 'UTF-8'def books = builder.bind { mkp.xmlDeclaration() namespaces << [meta:'http://meta/book/info'] books(count: 3) { book(id: 1) { title lang:'en', 'Groovy in Action' meta.isbn '1-932394-84-2' } book(id: 2) { title lang:'en', 'Groovy Programming' meta.isbn '0123725070' } book(id: 3) { title 'Groovy & Grails' comment << 'Not yet available.' } book(id: 4) { mkp.yieldUnescaped '<title>Griffon Guide</title>' } }}
println XmlUtil.serialize(books)
Builders = Metaprogramming Magic
<?xml version="1.0" encoding="UTF-8"?><books xmlns:meta="http://meta/book/info" count="3"> <book id="1"> <title lang="en">Groovy in Action</title> <meta:isbn>1-932394-84-2</meta:isbn> </book> <book id="2"> <title lang="en">Groovy Programming</title> <meta:isbn>0123725070</meta:isbn> </book> <book id="3"> <title>Groovy & Grails</title> <!--Not yet available.--> </book> <book id="4"> <title>Griffon Guide</title> </book></books>
Monday, June 7, 2010
![Page 8: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/8.jpg)
book(id: 2) { title lang:'en', 'Groovy Programming' meta.isbn '0123725070'}
XML Builders = An alternative Syntax for XML
<book id="2"> <title lang="en">Groovy Programming</title> <meta:isbn>0123725070</meta:isbn></book>
Monday, June 7, 2010
![Page 9: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/9.jpg)
But How?(is it code or is it data?)
Any sufficiently advanced technology is indistinguishable from magic.
Arthur C. Clarke,English physicist & science fiction author (1917 - )
def builder = new StreamingMarkupBuilder()builder.encoding = 'UTF-8'def books = builder.bind { mkp.xmlDeclaration() namespaces << [meta:'http://meta/book/info'] books(count: 3) { book(id: 1) { title lang:'en', 'Groovy in Action' meta.isbn '1-932394-84-2' } book(id: 2) { title lang:'en', 'Groovy Programming' meta.isbn '0123725070' } book(id: 3) { title 'Groovy & Grails' // & is converted to & comment << 'Not yet available.' } book(id: 4) { mkp.yieldUnescaped '<title>Griffon Guide</title>' } }}
println XmlUtil.serialize(books)
Monday, June 7, 2010
![Page 10: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/10.jpg)
The Answer Lies in Groovy’s Nature As a Dynamic Language
(as distinguished from java)
compile time
Java
run time
compile time
Groovy
run time
Monday, June 7, 2010
![Page 11: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/11.jpg)
Java Compilation
javasource
bytecode
Monday, June 7, 2010
![Page 12: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/12.jpg)
Groovy Compilation
groovysource
bytecode
metaprogram
Monday, June 7, 2010
![Page 13: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/13.jpg)
The Program Generated...
Evaluates Your Program At Runtime...
...it does so using a framework that is designed for you to plug into...
When you do so you are “programming the program”...
i.e. metaprogramming.
Monday, June 7, 2010
![Page 14: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/14.jpg)
This framework is called the “Meta Object Protocol”
(“protocol” in the sense of an “api”)
MOPMonday, June 7, 2010
![Page 15: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/15.jpg)
If you’re familiar with a framework like Struts...
This really isn’t that different:
Instead of mapping url requests to the code that handles them, you’re mapping actual method calls and property accesses to the code that handles them!
Instead of using struts-config.xml to do the mapping, you’re using actual code in the form of data structures called “meta classes”
The simplest and coolest of these is called the ExpandoMetaClass!
Monday, June 7, 2010
![Page 16: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/16.jpg)
All Groovy Objects Implement...
public interface GroovyObject {
Object invokeMethod(String name, Object args);
Object getProperty(String propertyName);
void setProperty(String propertyName, Object newValue);
MetaClass getMetaClass();
void setMetaClass(MetaClass metaClass);}
(This the heartbeat of the MOP)
Monday, June 7, 2010
![Page 17: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/17.jpg)
MetaClasses Implement these methods for a classand thereby define the behavior of the class.
Object invokeMethod(String name, Object args);
Object getProperty(String propertyName);
void setProperty(String propertyName, Object newValue);
The beauty of ExpandoMetaClass is that you can add methods and properties to classes simply by assigning
them - it expands indefinitely (like a Map).
Monday, June 7, 2010
![Page 18: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/18.jpg)
So The Magic Is Revealed(dynamic dispatch and missing methods)
<?xml version="1.0" encoding="UTF-8"?><books xmlns:meta="http://meta/book/info" count="3"> <book id="1"> <title lang="en">Groovy in Action</title> <meta:isbn>1-932394-84-2</meta:isbn> </book> <book id="2"> <title lang="en">Groovy Programming</title> <meta:isbn>0123725070</meta:isbn> </book> <book id="3"> <title>Groovy & Grails</title> <!--Not yet available.--> </book> <book id="4"> <title>Griffon Guide</title> </book></books>
def builder = new StreamingMarkupBuilder()builder.encoding = 'UTF-8'def books = builder.bind { mkp.xmlDeclaration() namespaces << [meta:'http://meta/book/info'] books(count: 3) { book(id: 1) { title lang:'en', 'Groovy in Action' meta.isbn '1-932394-84-2' } book(id: 2) { title lang:'en', 'Groovy Programming' meta.isbn '0123725070' } book(id: 3) { title 'Groovy & Grails' // & is converted to & comment << 'Not yet available.' } book(id: 4) { mkp.yieldUnescaped '<title>Griffon Guide</title>' } }}
println XmlUtil.serialize(books)
Monday, June 7, 2010
![Page 19: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/19.jpg)
When it comes to Groovy’s syntax...What you can write is fixed by the
parser (like most languages)...
but there’s lots of optional stuff
optional “()“, optional “;”, optional “[]” (sometimes)...
so much optional it sounds nuts!
but there’s a method to the madness.
Monday, June 7, 2010
![Page 20: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/20.jpg)
Combining the MOP with Groovy’s loose syntax...
You can highjack the meaning behind what the evaluator thinks
are method or property calls
but which supericially look more “declarative” than imperative
more “what” than “how”
the result can be shorter and clearer than java
Monday, June 7, 2010
![Page 21: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/21.jpg)
Grails uses this stuff a lot...It has a lot of these “domain specific languages” or
“DSL”s
but this talk is about groovy it’s not about grails
But grails is the best example of where these approaches are used all over the place to do amazing things with just a
little code...so this talk is about grails
DSL
But it’s notit’s about how grails does things under the covers
about how *groovy* does things under the covers
so this is a meta talk about grailsExactly (exact-o-mundo)
Monday, June 7, 2010
![Page 22: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/22.jpg)
And DSLs aren’t the only thing
The combination of closures and metaclasses can allow much coolness including:
AOP
IOC
Memoization
RMI via REST
(well, at least the factory pattern)
(a fancy word for caching)
(how many acronyms you gonna use?)
(without the AOP)(coolness = productivity)
Monday, June 7, 2010
![Page 23: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/23.jpg)
The preceding will be demonstrated with some delightful code examples.
But first...
Monday, June 7, 2010
![Page 24: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/24.jpg)
A Review of Closures for Newbies...
A java assignment:int val = 3;
A java function:public int func(int a, int b) { return a + b;}
Or in Groovy:def val = 3
A groovy function:def func(a, b) { a + b}
Monday, June 7, 2010
![Page 25: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/25.jpg)
A Review of Closures for Newbies...
def func = (a, b) { a + b}
Closures are anonymous functions that can be assigned as *values*...
From the previously slide you can *almost* guess the syntax:
Close! Above itʼs the variable that holds the name so itʼs on the left thatʼs correct. The wrong part is the parameters:
def func = { a, b -> a + b}
Groovyʼs syntax is nice because the “{“ and “}” clearly mark the “code block”.
Monday, June 7, 2010
![Page 26: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/26.jpg)
A Review of Closures for Newbies...
def class Counter { int count
def increment = { count ++ }}
One more thing about closures - regarding scoping...
A closure defined in the lexical scope of other code can refer to itʼs variables. This surrounding code is the “owner”:
But when closures are assigned to other objects, thereʼs more to life than just the surrounding code - esp. note the delegate:
this: as in Java, this refers to the instance of the enclosing class where a Closure is definedowner : the enclosing object (this or a surrounding Closure)delegate : by default the same as owner, but changeable for example in a builder or ExpandoMetaClass
Monday, June 7, 2010
![Page 27: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/27.jpg)
A Review of Closures for Newbies...
def postiveOnly(Closure c) { list.each { val -> if(val > 0) c.call(val) }}
Oh! And one more thing about closures...Groovy has syntactic sugar which allows a function taking a closure as itʼs final argument can be called with the closure passed after the functions closing paren:
Can be called like so:
postiveOnly { val -> println “$val is > 0” }
And lastly: the default parameter if none is specified is simply “it”:
postiveOnly { println “$it is > 0” }
Monday, June 7, 2010
![Page 28: Groovy Metaprogramming for Dummies](https://reader033.vdocument.in/reader033/viewer/2022052509/55accd621a28ab392c8b4680/html5/thumbnails/28.jpg)
Finally: some real metaprogramming...
String.metaClass.shout = { delegate.toUpperCase(); }println "Groovy".shout()
Add a method to a class:
And yes, you could even:
(but just because you can doesnʼt mean you will)
This just shows what a flexible and powerful language groovy is.
postiveOnly { println “$it is > 0” }
String.metaClass.toUpperCase = { delegate.toLowerCase(); }println "Groovy".toUpperCase()
A programming language for grownups.
(with a silly name)
Monday, June 7, 2010