13
© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission. Metaprogramming With The Groovy Runtime – Part 1 of 2 Jeff Scott Brown @jeffscottbrown [email protected]

Metaprogramming With The Groovy Runtime - Part 1 of 2

Embed Size (px)

DESCRIPTION

Speaker: Jeff Scott Brown The dynamic runtime nature of Groovy is one of the things that sets it apart from standard Java and makes it a fantastic language for building dynamic applications for the Java Platform. The metaprogramming capabilities offered by the language provide everything that an application development team needs to build systems that are far more capable than their all Java counterparts. This Part 1 of 2 will cover the runtime metaprogramming capabilities of Groovy. The session will dive deep into Groovy's Meta Object Protocol (MOP) which implements the incredibly dynamic runtime dispatch mechanism. The session will include a lot of live code demonstrating really powerful runtime features of the language. This session is focused specifically on Groovy's runtime metaprogramming capabilities. Part 2 of 2 will cover Groovy's compile time metaprogramming capabilities.

Citation preview

Page 1: Metaprogramming With The Groovy Runtime - Part 1 of 2

© 2013 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Metaprogramming With The Groovy Runtime – Part 1 of 2

Jeff Scott Brown@jeffscottbrown

[email protected]

Page 2: Metaprogramming With The Groovy Runtime - Part 1 of 2

Metaprogramming● What Is It?

– behavior changes at runtime

– capabilities are introduced at runtime

– Wikipedia says...

“Metaprogramming is the writing of computer programs that write or manipulate other programs (or themselves)...”

Page 3: Metaprogramming With The Groovy Runtime - Part 1 of 2

Metaprogramming And Groovy● Groovy Lends Itself Well To Metaprogramming

– dynamic method dispatch

– method/property interception

– create methods at runtime

– JVM supports very dynamic behavior

● much cannot be easily tapped by Java the language

Page 4: Metaprogramming With The Groovy Runtime - Part 1 of 2

Expando

● Dynamically Expanding Objectdef myExpando = new Expando()

myExpando.favoriteLanguage = 'Groovy'

myExpando.addNumbers = { i, j -> i + j }

assert 'Groovy' == myExpando.favoriteLanguage

assert 100 == myExpando.addNumbers(60, 40)

assert myExpando.foo == null

Page 5: Metaprogramming With The Groovy Runtime - Part 1 of 2

Runtime Mappings

expando.favoriteLanguage = 'Groovy'// maps to...expando.setProperty('favoriteLanguage', 'Groovy')

expando.favoriteLanguage// maps to...expando.getProperty('favoriteLanguage')

expando.addNumbers(33, 66)// maps to...expando.invokeMethod('addNumbers', [33, 66] as Object[])

Page 6: Metaprogramming With The Groovy Runtime - Part 1 of 2

Our Own Expando

With Those 3 Simple Methods We Can Create Our Own Version Of Expando In 3 Minutes.

Let's Do That Now. Live Demo...

Page 7: Metaprogramming With The Groovy Runtime - Part 1 of 2

Closure Delegates● Closures May Be Assigned A “Delegate”● Closures Relay Method Calls To Their

Delegate● Useful For Creating DSLs And Builders● Same Closure May Be Executed In

Different Contexts With Different Delegates

Page 8: Metaprogramming With The Groovy Runtime - Part 1 of 2

Closure Delegatesdef myClosure = { append('First Line\n') append('Last Line\n')}// will fail because there is no 'append' methodmyClosure()

def buffer = new StringBuffer()def myClosure = { append('First Line\n') append('Last Line\n')}myClosure.delegate = buffer// will append to the StringBuffermyClosure()

Page 9: Metaprogramming With The Groovy Runtime - Part 1 of 2

Closure Delegates

class User {

String login String password String email Date age

static constraints = { login(length:5..15,blank:false,unique:true) password(length:5..15,blank:false) email(email:true,blank:false) age(min:new Date(),nullable:false) }}

Page 10: Metaprogramming With The Groovy Runtime - Part 1 of 2

MarkupBuilder

def mkp = new groovy.xml.MarkupBuilder()mkp.html { head { title('My MarkupBuilder Test') } body { h2('My Favorite Sites') ul { li('groovy.codehaus.org') li('grails.org') li('javajeff.blogspot.com') } }}

Remember that this is executable code. All of those tag names are method calls that are being intercepted by the builder.

Page 11: Metaprogramming With The Groovy Runtime - Part 1 of 2

MarkupBuilder

<html> <head> <title>My MarkupBuilder Test</title> </head> <body> <h2>My Favorite Sites</h2> <ul> <li>groovy.codehaus.org</li> <li>grails.org</li> <li>javajeff.blogspot.com</li> </ul> </body></html>

Page 12: Metaprogramming With The Groovy Runtime - Part 1 of 2

ExpandoMetaClass

String.metaClass.vowels = { delegate.findAll { it.toLowerCase().matches('[aeiou]') }}def message = 'Groovy Is A Great Language'println message.vowels()// ["o", "o", "I", "A", "e", "a", "a", "u", "a", "e"]

Page 13: Metaprogramming With The Groovy Runtime - Part 1 of 2

Thank You For Coming

Q & A