2. 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
3. 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
4. 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
8. 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
9. 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
10. 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
13. 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
14. This framework is called
the “Meta Object Protocol”
(“protocol” in the sense of an “api”)
MOPMonday, June 7, 2010
15. 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
16. 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
17. MetaClasses Implement these methods for a class
and 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
18. 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
19. 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
20. 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
21. 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 not
it’s about how grails does things under the covers
about how *groovy* does things under the covers
so this is a meta talk about grails
Exactly (exact-o-mundo)
Monday, June 7, 2010
22. 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
23. The preceding will be demonstrated with some
delightful code examples.
But first...
Monday, June 7, 2010
24. 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
25. 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
26. 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 defined
owner : 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
27. 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
28. 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