runtime metaprogramming with groovy

15
Runtime Metaprogramming With Groovy Jeff Scott Brown @jeffscottbrown [email protected]

Upload: spring-by-pivotal

Post on 12-Apr-2017

245 views

Category:

Technology


5 download

TRANSCRIPT

Page 1: Runtime Metaprogramming with Groovy

Runtime Metaprogramming

With GroovyJeff Scott Brown @jeffscottbrown

[email protected]

Page 2: Runtime Metaprogramming with Groovy

More at ociweb.com/grails

Page 3: Runtime Metaprogramming with Groovy

Copyright (c) 2015 Object Computing, Inc. All rights reserved.

WE ARE HIRING!

Groovy And Grails Project Work Grails 2 -> 3 Plugin Migrations Grails Plugin Development Expanding GORM’s Reach New Application Profiles Grails Core Development

[email protected]

Page 4: Runtime Metaprogramming with Groovy

Copyright (c) 2015 Object Computing, Inc. All rights reserved.

● What Is It? − behavior changes at runtime − capabilities are introduced at runtime − Wikipedia says...

Metaprogramming

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

Page 5: Runtime Metaprogramming with Groovy

Copyright (c) 2015 Object Computing, Inc. All rights reserved.

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 6: Runtime Metaprogramming with Groovy

Copyright (c) 2015 Object Computing, Inc. All rights reserved.

Expando● Dynamically Expanding Object

def 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 7: Runtime Metaprogramming with Groovy

Copyright (c) 2015 Object Computing, Inc. All rights reserved.

Runtime Mappingsexpando.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 8: Runtime Metaprogramming with Groovy

Copyright (c) 2015 Object Computing, Inc. All rights reserved.

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 9: Runtime Metaprogramming with Groovy

Copyright (c) 2015 Object Computing, Inc. All rights reserved.

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 10: Runtime Metaprogramming with Groovy

Copyright (c) 2015 Object Computing, Inc. All rights reserved.

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

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

Page 11: Runtime Metaprogramming with Groovy

Copyright (c) 2015 Object Computing, Inc. All rights reserved.

Closure Delegatesclass 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 12: Runtime Metaprogramming with Groovy

Copyright (c) 2015 Object Computing, Inc. All rights reserved.

MarkupBuilderdef 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 13: Runtime Metaprogramming with Groovy

Copyright (c) 2015 Object Computing, Inc. All rights reserved.

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 14: Runtime Metaprogramming with Groovy

Copyright (c) 2015 Object Computing, Inc. All rights reserved.

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 15: Runtime Metaprogramming with Groovy

Q&A

Jeff Scott Brown @jeffscottbrown

[email protected]