SlideShare une entreprise Scribd logo
1  sur  61
MetaProgramming
With
Groovy
Presentation by: Ali and Gaurav
Agenda
▣ Groovy Is Dynamic
▣ What is MetaProgramming?
▣ Runtime MetaProgramming
□ What is MOP?
□ Understanding Groovy
□ Meta Class
▣ Intercepting Methods Using MOP
□ InvokeMethod
□ GroovyInterceptable
□ Intercepting Methods using MetaClass
▣ MOP Method Injection
□ MetaClass
□ Categories
□ Mixins/Traits
Agenda (continues..)
▣ MOP Method Synthesis
▣ MOP Class Synthesis
▣ Compile-time MetaProgramming
□ AST and Compilation
□ Groovy AST Transformation
□ Global AST Transformation
□ Local AST Transformation
▣ Why we should use MetaProgramming?
▣ References
Groovy Is Dynamic
▣ Groovy allows "Delay" to runtime some
checks/decisions that are usually performed
during the compilation.
▣ Add properties/behaviours in runtime.
▣ Wide range of applicability
□ DSLs
□ Builders
□ Advanced logging, tracing, debugging & profiling
□ Allow organize the codebase better
That's why we can talk about Metaprogramming
in Groovy.
What is
MetaProgramming?
‘’
Metaprogramming is
the writing of computer
programs that write or
manipulate other
programs (or
themselves) as their
data.
- Wikipedia
Overview
The Groovy language supports two flavors of
metaprogramming:
▣ Runtime metaprogramming, and
▣ Compile-time metaprogramming.
The first one allows altering the class model and
the behavior of a program at runtime, while the
second only occurs at compile-time.
Runtime
MetaProgramming
Runtime MetaProgramming
▣ Groovy provides this through Meta-Object
Protocol (MOP).
▣ We can use MOP to:
□ Invoke methods dynamically
□ Synthesize classes and methods on the fly.
With runtime metaprogramming we can
postpone to runtime the decision to intercept,
inject and even synthesize methods of classes
and interfaces.
What is the Meta Object Protocol?
Understanding Groovy
For a deep understanding of Groovy MOP we
first need to understand Groovy objects and
Groovy’s method handling. In Groovy, we work
with three kinds of objects:
▣ POJO,
▣ POGO, and
▣ Groovy Interceptors
So, for each object Groovy allows
metaprogramming but in different manner.
continues...
▣ POJO - A regular Java object, whose class can be
written in Java or any other language for the JVM.
▣ POGO - A Groovy object, whose class is written in
Groovy. It extends java.lang.Object and implements
the groovy.lang.GroovyObject interface by default.
▣ Groovy Interceptor - A Groovy object that implements
the groovy.lang.GroovyInterceptable interface and has
method-interception capability, which we’ll discuss in
the GroovyInterceptable section.
For every method call Groovy checks whether the object is
a POJO or a POGO. For POJOs, Groovy fetches it’s
MetaClass from the groovy.lang.MetaClassRegistry and
delegates method invocation to it.
continues...
For POGOs, Groovy takes more steps, as illustrated below:
Meta Class
▣ MetaClass registry for each class.
▣ Collection of methods/properties.
▣ We can always modify the metaclass.
Intercepting
Methods Using MOP
Groovy Object Interface
GroovyObject has a default implementation in the
groovy.lang.GroovyObjectSupport class and it is responsible to
transfer invocation to the groovy.lang.MetaClass object. The
GroovyObject source looks like this:
package groovy.lang;
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);
}
1.
invokeMethod
invokeMethod
This invokeMethod is called when the method you called is not
present on a Groovy object. Example:
class InvokeMethodDemo {
def invokeMethod(String name, Object args) {
return "called invokeMethod $name $args"
}
def test() {
return 'method exists'
}
}
def invokeMethodDemo = new InvokeMethodDemo()
assert invokeMethodDemo.test() == 'method exists'
assert invokeMethodDemo.hello() == 'called invokeMethod hello []'
2.
GroovyInterceptable
GroovyInterceptable
▣ Classes compiled by Groovy implements GroovyObject
interface.
▣ We can implement GroovyInterceptable to hook into
the execution process.
package groovy.lang;
public interface GroovyInterceptable extends
GroovyObject {
}
When a Groovy object implements the
GroovyInterceptable interface, it’s invokeMethod() is called
for any method calls.
GroovyInterceptable Example
class InterceptionDemo implements GroovyInterceptable {
def definedMethod() {}
def invokeMethod(String name, Object args) {
"$name invokedMethod"
}
}
def interceptionDemo = new InterceptionDemo()
assert interceptionDemo.definedMethod() == 'definedMethod
invokedMethod'
assert interceptionDemo.someMethod() == 'someMethod
invokedMethod'
3.
Intercepting
Methods Using
MetaClass
Intercepting Methods using MetaClass
If we want to intercept all methods call but do not want to
implement the GroovyInterceptable interface we can
implement invokeMethod() on an object’s MetaClass.
▣ Groovy maintains a meta class of type MetaClass for
each class.
▣ Maintains a collection of all methods and properties of
A.
▣ If we can't modify the class source code or if it's a Java
class we can modify the meta-class.
▣ We can intercept methods by implementing the
invokeMethod() method on the MetaClass.
MetaClass Example
class InterceptionThroughMetaClassDemo {
void sayHello(String name) {
println "========> Hello $name"
}
}
InterceptionThroughMetaClassDemo.metaClass.invokeMethod = { String
methodName, Object args ->
println("Invoking method '$methodName' with args '$args'")
def method =
InterceptionThroughMetaClassDemo.metaClass.getMetaMethod(methodName,
args)
method?.invoke(delegate, args)
}
def demo = new InterceptionThroughMetaClassDemo()
demo.sayHello("ALI")
demo.sayHI("EVERYONE")
demo.anotherMethod()
MOP Method
Injection
MOP Method Injection
▣ In Groovy we can “open” a class at any time.
▣ Injecting methods at code-writing time; we
know the names of methods we want to add.
▣ Different techniques:
□ MetaClass
□ Categories
□ Extensions
□ Mixins / Traits
1.
MetaClass
Types of MetaClass
▣ MetaClassImpl: Default meta class, it's used in the vast
majority of case.
▣ ExpandoMetaClass: allow the addition or replacement
of methods, properties and constructors on the fly.
▣ Other meta classes used internally and for testing.
Note: This is only true for Groovy.
▣ In Grails all MetaClass are ExpandoMetaClass.
Adding Methods Using MetaClass
class StringUtils {
static String truncate(String text, Integer length, Boolean overflow = false) {
text.take(length) + (overflow ? '...' : '')
}
}
String chuckIpsum = "If you can see Chuck Norris, he can see you.
If you can not see Chuck Norris you may be only seconds away from death"
println StringUtils.truncate(chuckIpsum, 72)
println StringUtils.truncate(chuckIpsum, 72, true)
String.metaClass.truncateDemo = { Integer length, Boolean overflow = false ->
println "truncate string upto length $length"
delegate.take(length) + (overflow ? '...' : '')
}
assert chuckIpsum.truncateDemo(20, true) == StringUtils.truncate(chuckIpsum, 20, true)
Adding Properties Using MetaClass
class Utils {
}
def utilsInstance = new Utils()
Utils.metaClass.version = "3.0"
utilsInstance.metaClass.released = true
assert utilsInstance.version == "3.0"
assert utilsInstance.released == true
println("utilsInstance.version: $utilsInstance.version")
println("utilsInstance.released: $utilsInstance.released")
Continues.. (Example 2)
class ExpandoLite {
protected dynamicPropMap = [:]
void setProperty(String propName, val) {
dynamicPropMap[propName] = val
}
def getProperty(String propName) {
dynamicPropMap[propName]
}
}
class ExpandoLiteSpec extends
Specification {
void 'test property access'() {
given:
def ex = new ExpandoLite()
when:
ex.companyName = 'Nexthoughts'
then:
'Nexthoughts' == ex.companyName
}
}
Adding Constructors Using MetaClass
try {
println(new Integer(Calendar.instance))
}
catch (e) {
}
Integer.metaClass.constructor << { Calendar calendar ->
new Integer(calendar.get(Calendar.DATE))
}
println("Today's Date: ${new Integer(Calendar.instance)}")
Overriding Methods Using MetaClass
// Integer
assert '15' == 15.toString()
Integer.metaClass.toString = {
delegate == 15 ?
'The answer to life, the universe and everything' :
String.valueOf(delegate)
}
assert 15.toString() == 'The answer to life, the universe and everything'
assert 100.toString() == '100'
println("15.toString(): ${15.toString()}")
println("100.toString(): ${100.toString()}")
// Boolean
assert false.toBoolean() == false
Boolean.metaClass.toBoolean = { !delegate }
assert false.toBoolean() == true
println("false.toBoolean(): ${false.toBoolean()}")
2.
Categories
Categories
▣ Changes made to a MetaClass are “persistent”
and hard to revert.
▣ Categories are useful to change the meta
class in a confined small piece of code.
▣ A category can alter a class’ MetaClass.
▣ The MOP is modified in the closure and after
the closure execution, it resets to its old state.
▣ Category classes are not special.
Continues.. (Example 1)
class StringUtils {
static String truncate(String text, Integer length, Boolean overflow = false) {
text.take(length) + (overflow ? '...' : '')
}
}
use(StringUtils) {
println "Hello! Everyone.".truncate(5)
}
try {
println "Hi! Ali.".truncate(5)
} catch (MissingMethodException mme) {
println mme
}
Continues.. (Example 2)
class Distance {
def number
String toString() {
println("==========> ${number}")
"${number}"
}
}
@Category(Number)
class NumberCategory {
Distance getMeters() {
new Distance(number: this + 'm')
}
Distance getKiloMeters() {
new Distance(number: this + 'km')
}
}
use(NumberCategory) {
assert 10.kiloMeters.toString() == '10km'
assert 50.meters.toString() == '50m'
}
3.
Mixins / Traits
Mixins
▣ A mixin allow “bring in” or “mix in”
implementations from multiple classes.
▣ Groovy first call the mixed-in class.
▣ Mix multiple classes. The last added mixin
takes precedence.
▣ Override a method of a previous Mixin but not
methods in the meta class.
▣ Mixins cannot easily be un-done.
continues..
class SpidermanPower {
String spiderSense() {
"Using spider-sense..."
}
}
class SupermanPower {
String fly() {
"Flying..."
}
}
@Mixin([SpidermanPower])
class Person {}
def person = new Person()
assert person.spiderSense() == "Using spider-sense..."
assert !(person instanceof SpidermanPower)
Person.mixin SupermanPower
assert person.fly() == "Flying..."
assert !(person instanceof SupermanPower)
continues..
class SpidermanPower {
String spiderSense() {
"Using spider-sense..."
}
}
class SupermanPower {
String fly() {
"Flying..."
}
}
@Mixin([SpidermanPower])
class Person {}
def person = new Person()
assert person.spiderSense() == "Using spider-sense..."
assert !(person instanceof SpidermanPower)
Person.mixin SupermanPower
assert person.fly() == "Flying..."
assert !(person instanceof SupermanPower)
‘’
When we started fixing
mixin bugs we didn't
know if they were a
bug or a feature, so we
removed mixins and
add traits.
- Jochen Theodorou
▣ Groovy 2.3+
▣ Similar to Java 8 default methods
▣ Supported in JDK 6, 7 and 8
▣ Stateful
▣ Composition over inheritance
▣ Documentation
Traits
Note - Link to Groovy Traits PPT
Traits Example
trait SpidermanPower {
String spiderSense() {
"Using spider-sense..."
}
}
class Person implements SpidermanPower {}
def person = new Person()
assert person.spiderSense() == "Using spider-sense..."
println("=====> person.spiderSense(): ${person.spiderSense()}")
assert person instanceof SpidermanPower
def person2 = person.withTraits SupermanPower
assert person2.fly() == "Flying..."
println("=====> person2.fly(): ${person2.fly()}")
assert person2 instanceof SupermanPower
trait SupermanPower {
String fly() {
"Flying..."
}
}
MOP Method
Synthesis
MOP Method Synthesis
▣ Dynamically figure out the behaviour for
methods upon invocation.
▣ A synthesized method may not exist as a
separate method until we call it.
▣ invokeMethod, methodMissing and
propertyMissing.
▣ “Intercept, Cache, Invoke” pattern.
Check for Methods and Properties
class Person {
String name
Integer age
String sayHi() {
"Hi, my name is ${name} and I'm ${age}"
}
String sayHiTo(String name) {
"Hi ${name}, how are you?"
}
}
def p = new Person(name: 'Superman',
age: 34)
assert p.respondsTo('sayHi')
assert p.respondsTo('sayHiTo', String)
assert !p.respondsTo('goodbye')
assert p.hasProperty('name')
assert !p.hasProperty('country')
Method Delegation
cl = { ->
append "Hi!"
append " this is closure delegate demo."
}
sb = new StringBuffer()
cl.delegate = sb
cl()
println "SB: ${sb}"
Continues.. (Example 2)
class ClosureDemo {
void append(String arg) {
println("append called with: ${arg}")
}
void doit() {
def cl = {
append 'MetaProgramming Demo by'
append ' Ali and Gaurav'
}
def sb = new StringBuffer()
cl.delegate = sb
cl()
println("SB: ${sb}")
}
static void main(args) {
new ClosureDemo().doit()
}
}
MOP Class Synthesis
Creating Dynamic Classes with
Expando
carA = new Expando()
carB = new Expando(year: 2012, miles: 0)
carA.year = 2012
carA.miles = 10
println "carA: " + carA
println "carB: " + carB
In Groovy we can create a class entirely at runtime. The
Groovy Expando class gives us the ability to synthesize
classes dynamically.
It got its name because it is dynamically expandable. We can
assign properties and methods to it either at construction
time using a Map or at any time dynamically.
car = new Expando(year: 2012, miles: 0,
turn: { println 'turning...' })
car.drive = {
miles += 10
println "$miles miles driven"
}
car.drive()
car.turn()
Compile-time
MetaProgramming?
Compile-time MetaProgramming
▣ Advanced feature.
▣ Analyze and modify a program’s structure at
compile time.
▣ Cross-cutting features:
▣ Inspect classes for thread safety
▣ Log messages
▣ Perform pre and postcheck operations all
without explicitly modifying the source code.
▣ We write code that generates bytecode or
gets involved during the bytecode
generation.
AST and Compilation
▣ AST: Abstract Syntax Tree
▣ During compilation the AST is transformed
▣ Hook into different phases to change the final
byte-code.
▣ Initialization, Parsing, Conversion, Semantic
analysis, Canonicalization, Instruction
selection, Class generation, Output,
Finalization.
Groovy AST Transformations
▣ Groovy provides out-of-the-box a lot of AST
Transformations
▣ @EqualsAndHashCode, @ToString,
@TuppleConstructor, @Canonical, @Grab,
@Immutable, @Delegate, @Singleton,
@Category, @Log4j, @CompileStatic,
@TypeChecked, @Synchronized, etc.
Global AST Transformations
▣ There's no need to annotate anything.
▣ Applied to every single source unit during
compilation.
▣ Can be applied to any phase in the
compilation.
▣ Need a metadata file into the JAR file
▣ (META-
INF/services/org.codehaus.groovy.transform.
ASTTransformation)
▣ Grails uses Global Transformations intensively
for example in GORM.
Local AST Transformations
▣ Annotate the code and only applied to that
code.
▣ Easy to debug.
▣ No need to create metadata file in a jar.
▣ Steps: Define an interface, Define the AST
transformation, Enjoy!
Why we should use
MetaProgramming?
Concept Review
▣ Metaprogramming Easy and very out-of-the
box
▣ Easy and very powerful
▣ Write better code
▣ Add Behaviour easily
▣ Take advantage of this power because
Groovy, it’s Groovy
References
▣ http://groovy-lang.org/metaprogramming.html
▣ http://www.slideshare.net/ilopmar/metaprogrammin
g-with-groovy
▣ http://www.slideshare.net/ilopmar/gr8conf-2016-
metaprogramming-with-groovy
Thanks!
Any questions?
You can find us at -
▣ ali.tanwir@nexthoughts.com
▣ gaurav.gupta@nexthoughts.com
You can find demo code used with this presentation at -
https://github.com/NexThoughts/groovyMetaProgrammin
g

Contenu connexe

Tendances

Embedding Groovy in a Java Application
Embedding Groovy in a Java ApplicationEmbedding Groovy in a Java Application
Embedding Groovy in a Java ApplicationPaolo Predonzani
 
Jython 2.7 and techniques for integrating with Java - Frank Wierzbicki
Jython 2.7 and techniques for integrating with Java - Frank WierzbickiJython 2.7 and techniques for integrating with Java - Frank Wierzbicki
Jython 2.7 and techniques for integrating with Java - Frank Wierzbickifwierzbicki
 
eXo EC - Groovy Programming Language
eXo EC - Groovy Programming LanguageeXo EC - Groovy Programming Language
eXo EC - Groovy Programming LanguageHoat Le
 
Inside the JVM - Follow the white rabbit! / Breizh JUG
Inside the JVM - Follow the white rabbit! / Breizh JUGInside the JVM - Follow the white rabbit! / Breizh JUG
Inside the JVM - Follow the white rabbit! / Breizh JUGSylvain Wallez
 
Communication between Java and Python
Communication between Java and PythonCommunication between Java and Python
Communication between Java and PythonAndreas Schreiber
 
Using the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentUsing the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentSchalk Cronjé
 
Future Programming Language
Future Programming LanguageFuture Programming Language
Future Programming LanguageYLTO
 
Better DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseBetter DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseAndrew Eisenberg
 
Smalltalk on the JVM
Smalltalk on the JVMSmalltalk on the JVM
Smalltalk on the JVMESUG
 
Introduction To Grails
Introduction To GrailsIntroduction To Grails
Introduction To GrailsEric Berry
 
Java Hates Linux. Deal With It.
Java Hates Linux.  Deal With It.Java Hates Linux.  Deal With It.
Java Hates Linux. Deal With It.Greg Banks
 

Tendances (20)

What's New in Groovy 1.6?
What's New in Groovy 1.6?What's New in Groovy 1.6?
What's New in Groovy 1.6?
 
Groovy intro
Groovy introGroovy intro
Groovy intro
 
Meta Programming in Groovy
Meta Programming in GroovyMeta Programming in Groovy
Meta Programming in Groovy
 
Introduction to jython
Introduction to jythonIntroduction to jython
Introduction to jython
 
Embedding Groovy in a Java Application
Embedding Groovy in a Java ApplicationEmbedding Groovy in a Java Application
Embedding Groovy in a Java Application
 
Jython 2.7 and techniques for integrating with Java - Frank Wierzbicki
Jython 2.7 and techniques for integrating with Java - Frank WierzbickiJython 2.7 and techniques for integrating with Java - Frank Wierzbicki
Jython 2.7 and techniques for integrating with Java - Frank Wierzbicki
 
eXo EC - Groovy Programming Language
eXo EC - Groovy Programming LanguageeXo EC - Groovy Programming Language
eXo EC - Groovy Programming Language
 
Whats New In Groovy 1.6?
Whats New In Groovy 1.6?Whats New In Groovy 1.6?
Whats New In Groovy 1.6?
 
Inside the JVM - Follow the white rabbit! / Breizh JUG
Inside the JVM - Follow the white rabbit! / Breizh JUGInside the JVM - Follow the white rabbit! / Breizh JUG
Inside the JVM - Follow the white rabbit! / Breizh JUG
 
Groovy & Grails
Groovy & GrailsGroovy & Grails
Groovy & Grails
 
Communication between Java and Python
Communication between Java and PythonCommunication between Java and Python
Communication between Java and Python
 
Viva file
Viva fileViva file
Viva file
 
Using the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentUsing the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM Development
 
Exploring lambdas and invokedynamic for embedded systems
Exploring lambdas and invokedynamic for embedded systemsExploring lambdas and invokedynamic for embedded systems
Exploring lambdas and invokedynamic for embedded systems
 
Future Programming Language
Future Programming LanguageFuture Programming Language
Future Programming Language
 
Better DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseBetter DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-Eclipse
 
Smalltalk on the JVM
Smalltalk on the JVMSmalltalk on the JVM
Smalltalk on the JVM
 
Introduction To Grails
Introduction To GrailsIntroduction To Grails
Introduction To Grails
 
Java For Automation
Java   For AutomationJava   For Automation
Java For Automation
 
Java Hates Linux. Deal With It.
Java Hates Linux.  Deal With It.Java Hates Linux.  Deal With It.
Java Hates Linux. Deal With It.
 

En vedette

Groovy Powered Clean Code
Groovy Powered Clean CodeGroovy Powered Clean Code
Groovy Powered Clean CodeGR8Conf
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with GroovyGR8Conf
 
Groovy in the Cloud
Groovy in the CloudGroovy in the Cloud
Groovy in the CloudDaniel Woods
 
Kotlin, smarter development for the jvm
Kotlin, smarter development for the jvmKotlin, smarter development for the jvm
Kotlin, smarter development for the jvmArnaud Giuliani
 
Spring one 2012 Groovy as a weapon of maas PaaSification
Spring one 2012 Groovy as a weapon of maas PaaSificationSpring one 2012 Groovy as a weapon of maas PaaSification
Spring one 2012 Groovy as a weapon of maas PaaSificationNenad Bogojevic
 
Java collections the force awakens
Java collections  the force awakensJava collections  the force awakens
Java collections the force awakensRichardWarburton
 
We thought we were doing continuous delivery and then...
We thought we were doing continuous delivery and then... We thought we were doing continuous delivery and then...
We thought we were doing continuous delivery and then... Suzie Prince
 
Groovy for java developers
Groovy for java developersGroovy for java developers
Groovy for java developersPuneet Behl
 
Reactive Streams and the Wide World of Groovy
Reactive Streams and the Wide World of GroovyReactive Streams and the Wide World of Groovy
Reactive Streams and the Wide World of GroovySteve Pember
 
Be More Productive with Kotlin
Be More Productive with KotlinBe More Productive with Kotlin
Be More Productive with KotlinBrandon Wever
 
Groovy on Android (as of 2016)
Groovy on Android (as of 2016)Groovy on Android (as of 2016)
Groovy on Android (as of 2016)Kevin H.A. Tan
 
Building an Extensible, Resumable DSL on Top of Apache Groovy
Building an Extensible, Resumable DSL on Top of Apache GroovyBuilding an Extensible, Resumable DSL on Top of Apache Groovy
Building an Extensible, Resumable DSL on Top of Apache Groovyjgcloudbees
 
Java 8 and 9 in Anger
Java 8 and 9 in AngerJava 8 and 9 in Anger
Java 8 and 9 in AngerTrisha Gee
 
Kotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRreadyKotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRreadyMobileAcademy
 
Groovyscriptingformanualandautomationtestingusingrobotframework 141221014703-...
Groovyscriptingformanualandautomationtestingusingrobotframework 141221014703-...Groovyscriptingformanualandautomationtestingusingrobotframework 141221014703-...
Groovyscriptingformanualandautomationtestingusingrobotframework 141221014703-...Bhaskara Reddy Sannapureddy
 
Java 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually useJava 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually useSharon Rozinsky
 

En vedette (20)

Introduction To Grails
Introduction To GrailsIntroduction To Grails
Introduction To Grails
 
Grails Overview
Grails OverviewGrails Overview
Grails Overview
 
Groovy Powered Clean Code
Groovy Powered Clean CodeGroovy Powered Clean Code
Groovy Powered Clean Code
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with Groovy
 
Groovy on Android
Groovy on AndroidGroovy on Android
Groovy on Android
 
Groovy in the Cloud
Groovy in the CloudGroovy in the Cloud
Groovy in the Cloud
 
Ci for-android-apps
Ci for-android-appsCi for-android-apps
Ci for-android-apps
 
Kotlin, smarter development for the jvm
Kotlin, smarter development for the jvmKotlin, smarter development for the jvm
Kotlin, smarter development for the jvm
 
Spring one 2012 Groovy as a weapon of maas PaaSification
Spring one 2012 Groovy as a weapon of maas PaaSificationSpring one 2012 Groovy as a weapon of maas PaaSification
Spring one 2012 Groovy as a weapon of maas PaaSification
 
Java collections the force awakens
Java collections  the force awakensJava collections  the force awakens
Java collections the force awakens
 
We thought we were doing continuous delivery and then...
We thought we were doing continuous delivery and then... We thought we were doing continuous delivery and then...
We thought we were doing continuous delivery and then...
 
Groovy for java developers
Groovy for java developersGroovy for java developers
Groovy for java developers
 
Reactive Streams and the Wide World of Groovy
Reactive Streams and the Wide World of GroovyReactive Streams and the Wide World of Groovy
Reactive Streams and the Wide World of Groovy
 
Be More Productive with Kotlin
Be More Productive with KotlinBe More Productive with Kotlin
Be More Productive with Kotlin
 
Groovy on Android (as of 2016)
Groovy on Android (as of 2016)Groovy on Android (as of 2016)
Groovy on Android (as of 2016)
 
Building an Extensible, Resumable DSL on Top of Apache Groovy
Building an Extensible, Resumable DSL on Top of Apache GroovyBuilding an Extensible, Resumable DSL on Top of Apache Groovy
Building an Extensible, Resumable DSL on Top of Apache Groovy
 
Java 8 and 9 in Anger
Java 8 and 9 in AngerJava 8 and 9 in Anger
Java 8 and 9 in Anger
 
Kotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRreadyKotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRready
 
Groovyscriptingformanualandautomationtestingusingrobotframework 141221014703-...
Groovyscriptingformanualandautomationtestingusingrobotframework 141221014703-...Groovyscriptingformanualandautomationtestingusingrobotframework 141221014703-...
Groovyscriptingformanualandautomationtestingusingrobotframework 141221014703-...
 
Java 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually useJava 8 new features or the ones you might actually use
Java 8 new features or the ones you might actually use
 

Similaire à Metaprogramming with Groovy

JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...Guillaume Laforge
 
Grooscript gr8conf
Grooscript gr8confGrooscript gr8conf
Grooscript gr8confGR8Conf
 
Groovy And Grails JUG Padova
Groovy And Grails JUG PadovaGroovy And Grails JUG Padova
Groovy And Grails JUG PadovaJohn Leach
 
Object Oriented Programming with Java
Object Oriented Programming with JavaObject Oriented Programming with Java
Object Oriented Programming with Javabackdoor
 
Groovy And Grails JUG Sardegna
Groovy And Grails JUG SardegnaGroovy And Grails JUG Sardegna
Groovy And Grails JUG SardegnaJohn Leach
 
Apache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and YouApache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and YouAndres Almiray
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Do you really get class loaders?
Do you really get class loaders? Do you really get class loaders?
Do you really get class loaders? guestd56374
 
oops concept in java | object oriented programming in java
oops concept in java | object oriented programming in javaoops concept in java | object oriented programming in java
oops concept in java | object oriented programming in javaCPD INDIA
 
Advanced java jee material by KV Rao sir
Advanced java jee material by KV Rao sirAdvanced java jee material by KV Rao sir
Advanced java jee material by KV Rao sirAVINASH KUMAR
 
Framework prototype
Framework prototypeFramework prototype
Framework prototypeDevMix
 
Framework prototype
Framework prototypeFramework prototype
Framework prototypeDevMix
 
Framework prototype
Framework prototypeFramework prototype
Framework prototypeDevMix
 
Groovy Metaprogramming for Dummies
Groovy Metaprogramming for DummiesGroovy Metaprogramming for Dummies
Groovy Metaprogramming for DummiesDarren Cruse
 
Introduction to OOP with PHP
Introduction to OOP with PHPIntroduction to OOP with PHP
Introduction to OOP with PHPMichael Peacock
 

Similaire à Metaprogramming with Groovy (20)

JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
 
Grooscript gr8conf
Grooscript gr8confGrooscript gr8conf
Grooscript gr8conf
 
Groovy Testing
Groovy TestingGroovy Testing
Groovy Testing
 
Svcc Groovy Testing
Svcc Groovy TestingSvcc Groovy Testing
Svcc Groovy Testing
 
Groovy And Grails JUG Padova
Groovy And Grails JUG PadovaGroovy And Grails JUG Padova
Groovy And Grails JUG Padova
 
groovy & grails - lecture 7
groovy & grails - lecture 7groovy & grails - lecture 7
groovy & grails - lecture 7
 
Soaoui
SoaouiSoaoui
Soaoui
 
Object Oriented Programming with Java
Object Oriented Programming with JavaObject Oriented Programming with Java
Object Oriented Programming with Java
 
Groovy And Grails JUG Sardegna
Groovy And Grails JUG SardegnaGroovy And Grails JUG Sardegna
Groovy And Grails JUG Sardegna
 
Apache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and YouApache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and You
 
Object oriented concepts
Object oriented conceptsObject oriented concepts
Object oriented concepts
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Do you really get class loaders?
Do you really get class loaders? Do you really get class loaders?
Do you really get class loaders?
 
oops concept in java | object oriented programming in java
oops concept in java | object oriented programming in javaoops concept in java | object oriented programming in java
oops concept in java | object oriented programming in java
 
Advanced java jee material by KV Rao sir
Advanced java jee material by KV Rao sirAdvanced java jee material by KV Rao sir
Advanced java jee material by KV Rao sir
 
Framework prototype
Framework prototypeFramework prototype
Framework prototype
 
Framework prototype
Framework prototypeFramework prototype
Framework prototype
 
Framework prototype
Framework prototypeFramework prototype
Framework prototype
 
Groovy Metaprogramming for Dummies
Groovy Metaprogramming for DummiesGroovy Metaprogramming for Dummies
Groovy Metaprogramming for Dummies
 
Introduction to OOP with PHP
Introduction to OOP with PHPIntroduction to OOP with PHP
Introduction to OOP with PHP
 

Dernier

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 

Dernier (20)

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 

Metaprogramming with Groovy

  • 2. Agenda ▣ Groovy Is Dynamic ▣ What is MetaProgramming? ▣ Runtime MetaProgramming □ What is MOP? □ Understanding Groovy □ Meta Class ▣ Intercepting Methods Using MOP □ InvokeMethod □ GroovyInterceptable □ Intercepting Methods using MetaClass ▣ MOP Method Injection □ MetaClass □ Categories □ Mixins/Traits
  • 3. Agenda (continues..) ▣ MOP Method Synthesis ▣ MOP Class Synthesis ▣ Compile-time MetaProgramming □ AST and Compilation □ Groovy AST Transformation □ Global AST Transformation □ Local AST Transformation ▣ Why we should use MetaProgramming? ▣ References
  • 4. Groovy Is Dynamic ▣ Groovy allows "Delay" to runtime some checks/decisions that are usually performed during the compilation. ▣ Add properties/behaviours in runtime. ▣ Wide range of applicability □ DSLs □ Builders □ Advanced logging, tracing, debugging & profiling □ Allow organize the codebase better That's why we can talk about Metaprogramming in Groovy.
  • 6. ‘’ Metaprogramming is the writing of computer programs that write or manipulate other programs (or themselves) as their data. - Wikipedia
  • 7. Overview The Groovy language supports two flavors of metaprogramming: ▣ Runtime metaprogramming, and ▣ Compile-time metaprogramming. The first one allows altering the class model and the behavior of a program at runtime, while the second only occurs at compile-time.
  • 9. Runtime MetaProgramming ▣ Groovy provides this through Meta-Object Protocol (MOP). ▣ We can use MOP to: □ Invoke methods dynamically □ Synthesize classes and methods on the fly. With runtime metaprogramming we can postpone to runtime the decision to intercept, inject and even synthesize methods of classes and interfaces.
  • 10. What is the Meta Object Protocol?
  • 11. Understanding Groovy For a deep understanding of Groovy MOP we first need to understand Groovy objects and Groovy’s method handling. In Groovy, we work with three kinds of objects: ▣ POJO, ▣ POGO, and ▣ Groovy Interceptors So, for each object Groovy allows metaprogramming but in different manner.
  • 12. continues... ▣ POJO - A regular Java object, whose class can be written in Java or any other language for the JVM. ▣ POGO - A Groovy object, whose class is written in Groovy. It extends java.lang.Object and implements the groovy.lang.GroovyObject interface by default. ▣ Groovy Interceptor - A Groovy object that implements the groovy.lang.GroovyInterceptable interface and has method-interception capability, which we’ll discuss in the GroovyInterceptable section. For every method call Groovy checks whether the object is a POJO or a POGO. For POJOs, Groovy fetches it’s MetaClass from the groovy.lang.MetaClassRegistry and delegates method invocation to it.
  • 13. continues... For POGOs, Groovy takes more steps, as illustrated below:
  • 14. Meta Class ▣ MetaClass registry for each class. ▣ Collection of methods/properties. ▣ We can always modify the metaclass.
  • 16. Groovy Object Interface GroovyObject has a default implementation in the groovy.lang.GroovyObjectSupport class and it is responsible to transfer invocation to the groovy.lang.MetaClass object. The GroovyObject source looks like this: package groovy.lang; 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); }
  • 18. invokeMethod This invokeMethod is called when the method you called is not present on a Groovy object. Example: class InvokeMethodDemo { def invokeMethod(String name, Object args) { return "called invokeMethod $name $args" } def test() { return 'method exists' } } def invokeMethodDemo = new InvokeMethodDemo() assert invokeMethodDemo.test() == 'method exists' assert invokeMethodDemo.hello() == 'called invokeMethod hello []'
  • 20. GroovyInterceptable ▣ Classes compiled by Groovy implements GroovyObject interface. ▣ We can implement GroovyInterceptable to hook into the execution process. package groovy.lang; public interface GroovyInterceptable extends GroovyObject { } When a Groovy object implements the GroovyInterceptable interface, it’s invokeMethod() is called for any method calls.
  • 21. GroovyInterceptable Example class InterceptionDemo implements GroovyInterceptable { def definedMethod() {} def invokeMethod(String name, Object args) { "$name invokedMethod" } } def interceptionDemo = new InterceptionDemo() assert interceptionDemo.definedMethod() == 'definedMethod invokedMethod' assert interceptionDemo.someMethod() == 'someMethod invokedMethod'
  • 23. Intercepting Methods using MetaClass If we want to intercept all methods call but do not want to implement the GroovyInterceptable interface we can implement invokeMethod() on an object’s MetaClass. ▣ Groovy maintains a meta class of type MetaClass for each class. ▣ Maintains a collection of all methods and properties of A. ▣ If we can't modify the class source code or if it's a Java class we can modify the meta-class. ▣ We can intercept methods by implementing the invokeMethod() method on the MetaClass.
  • 24. MetaClass Example class InterceptionThroughMetaClassDemo { void sayHello(String name) { println "========> Hello $name" } } InterceptionThroughMetaClassDemo.metaClass.invokeMethod = { String methodName, Object args -> println("Invoking method '$methodName' with args '$args'") def method = InterceptionThroughMetaClassDemo.metaClass.getMetaMethod(methodName, args) method?.invoke(delegate, args) } def demo = new InterceptionThroughMetaClassDemo() demo.sayHello("ALI") demo.sayHI("EVERYONE") demo.anotherMethod()
  • 26. MOP Method Injection ▣ In Groovy we can “open” a class at any time. ▣ Injecting methods at code-writing time; we know the names of methods we want to add. ▣ Different techniques: □ MetaClass □ Categories □ Extensions □ Mixins / Traits
  • 28. Types of MetaClass ▣ MetaClassImpl: Default meta class, it's used in the vast majority of case. ▣ ExpandoMetaClass: allow the addition or replacement of methods, properties and constructors on the fly. ▣ Other meta classes used internally and for testing. Note: This is only true for Groovy. ▣ In Grails all MetaClass are ExpandoMetaClass.
  • 29. Adding Methods Using MetaClass class StringUtils { static String truncate(String text, Integer length, Boolean overflow = false) { text.take(length) + (overflow ? '...' : '') } } String chuckIpsum = "If you can see Chuck Norris, he can see you. If you can not see Chuck Norris you may be only seconds away from death" println StringUtils.truncate(chuckIpsum, 72) println StringUtils.truncate(chuckIpsum, 72, true) String.metaClass.truncateDemo = { Integer length, Boolean overflow = false -> println "truncate string upto length $length" delegate.take(length) + (overflow ? '...' : '') } assert chuckIpsum.truncateDemo(20, true) == StringUtils.truncate(chuckIpsum, 20, true)
  • 30. Adding Properties Using MetaClass class Utils { } def utilsInstance = new Utils() Utils.metaClass.version = "3.0" utilsInstance.metaClass.released = true assert utilsInstance.version == "3.0" assert utilsInstance.released == true println("utilsInstance.version: $utilsInstance.version") println("utilsInstance.released: $utilsInstance.released")
  • 31. Continues.. (Example 2) class ExpandoLite { protected dynamicPropMap = [:] void setProperty(String propName, val) { dynamicPropMap[propName] = val } def getProperty(String propName) { dynamicPropMap[propName] } } class ExpandoLiteSpec extends Specification { void 'test property access'() { given: def ex = new ExpandoLite() when: ex.companyName = 'Nexthoughts' then: 'Nexthoughts' == ex.companyName } }
  • 32. Adding Constructors Using MetaClass try { println(new Integer(Calendar.instance)) } catch (e) { } Integer.metaClass.constructor << { Calendar calendar -> new Integer(calendar.get(Calendar.DATE)) } println("Today's Date: ${new Integer(Calendar.instance)}")
  • 33. Overriding Methods Using MetaClass // Integer assert '15' == 15.toString() Integer.metaClass.toString = { delegate == 15 ? 'The answer to life, the universe and everything' : String.valueOf(delegate) } assert 15.toString() == 'The answer to life, the universe and everything' assert 100.toString() == '100' println("15.toString(): ${15.toString()}") println("100.toString(): ${100.toString()}") // Boolean assert false.toBoolean() == false Boolean.metaClass.toBoolean = { !delegate } assert false.toBoolean() == true println("false.toBoolean(): ${false.toBoolean()}")
  • 35. Categories ▣ Changes made to a MetaClass are “persistent” and hard to revert. ▣ Categories are useful to change the meta class in a confined small piece of code. ▣ A category can alter a class’ MetaClass. ▣ The MOP is modified in the closure and after the closure execution, it resets to its old state. ▣ Category classes are not special.
  • 36. Continues.. (Example 1) class StringUtils { static String truncate(String text, Integer length, Boolean overflow = false) { text.take(length) + (overflow ? '...' : '') } } use(StringUtils) { println "Hello! Everyone.".truncate(5) } try { println "Hi! Ali.".truncate(5) } catch (MissingMethodException mme) { println mme }
  • 37. Continues.. (Example 2) class Distance { def number String toString() { println("==========> ${number}") "${number}" } } @Category(Number) class NumberCategory { Distance getMeters() { new Distance(number: this + 'm') } Distance getKiloMeters() { new Distance(number: this + 'km') } } use(NumberCategory) { assert 10.kiloMeters.toString() == '10km' assert 50.meters.toString() == '50m' }
  • 39. Mixins ▣ A mixin allow “bring in” or “mix in” implementations from multiple classes. ▣ Groovy first call the mixed-in class. ▣ Mix multiple classes. The last added mixin takes precedence. ▣ Override a method of a previous Mixin but not methods in the meta class. ▣ Mixins cannot easily be un-done.
  • 40. continues.. class SpidermanPower { String spiderSense() { "Using spider-sense..." } } class SupermanPower { String fly() { "Flying..." } } @Mixin([SpidermanPower]) class Person {} def person = new Person() assert person.spiderSense() == "Using spider-sense..." assert !(person instanceof SpidermanPower) Person.mixin SupermanPower assert person.fly() == "Flying..." assert !(person instanceof SupermanPower)
  • 41. continues.. class SpidermanPower { String spiderSense() { "Using spider-sense..." } } class SupermanPower { String fly() { "Flying..." } } @Mixin([SpidermanPower]) class Person {} def person = new Person() assert person.spiderSense() == "Using spider-sense..." assert !(person instanceof SpidermanPower) Person.mixin SupermanPower assert person.fly() == "Flying..." assert !(person instanceof SupermanPower)
  • 42. ‘’ When we started fixing mixin bugs we didn't know if they were a bug or a feature, so we removed mixins and add traits. - Jochen Theodorou
  • 43. ▣ Groovy 2.3+ ▣ Similar to Java 8 default methods ▣ Supported in JDK 6, 7 and 8 ▣ Stateful ▣ Composition over inheritance ▣ Documentation Traits Note - Link to Groovy Traits PPT
  • 44. Traits Example trait SpidermanPower { String spiderSense() { "Using spider-sense..." } } class Person implements SpidermanPower {} def person = new Person() assert person.spiderSense() == "Using spider-sense..." println("=====> person.spiderSense(): ${person.spiderSense()}") assert person instanceof SpidermanPower def person2 = person.withTraits SupermanPower assert person2.fly() == "Flying..." println("=====> person2.fly(): ${person2.fly()}") assert person2 instanceof SupermanPower trait SupermanPower { String fly() { "Flying..." } }
  • 46. MOP Method Synthesis ▣ Dynamically figure out the behaviour for methods upon invocation. ▣ A synthesized method may not exist as a separate method until we call it. ▣ invokeMethod, methodMissing and propertyMissing. ▣ “Intercept, Cache, Invoke” pattern.
  • 47. Check for Methods and Properties class Person { String name Integer age String sayHi() { "Hi, my name is ${name} and I'm ${age}" } String sayHiTo(String name) { "Hi ${name}, how are you?" } } def p = new Person(name: 'Superman', age: 34) assert p.respondsTo('sayHi') assert p.respondsTo('sayHiTo', String) assert !p.respondsTo('goodbye') assert p.hasProperty('name') assert !p.hasProperty('country')
  • 48. Method Delegation cl = { -> append "Hi!" append " this is closure delegate demo." } sb = new StringBuffer() cl.delegate = sb cl() println "SB: ${sb}"
  • 49. Continues.. (Example 2) class ClosureDemo { void append(String arg) { println("append called with: ${arg}") } void doit() { def cl = { append 'MetaProgramming Demo by' append ' Ali and Gaurav' } def sb = new StringBuffer() cl.delegate = sb cl() println("SB: ${sb}") } static void main(args) { new ClosureDemo().doit() } }
  • 51. Creating Dynamic Classes with Expando carA = new Expando() carB = new Expando(year: 2012, miles: 0) carA.year = 2012 carA.miles = 10 println "carA: " + carA println "carB: " + carB In Groovy we can create a class entirely at runtime. The Groovy Expando class gives us the ability to synthesize classes dynamically. It got its name because it is dynamically expandable. We can assign properties and methods to it either at construction time using a Map or at any time dynamically. car = new Expando(year: 2012, miles: 0, turn: { println 'turning...' }) car.drive = { miles += 10 println "$miles miles driven" } car.drive() car.turn()
  • 53. Compile-time MetaProgramming ▣ Advanced feature. ▣ Analyze and modify a program’s structure at compile time. ▣ Cross-cutting features: ▣ Inspect classes for thread safety ▣ Log messages ▣ Perform pre and postcheck operations all without explicitly modifying the source code. ▣ We write code that generates bytecode or gets involved during the bytecode generation.
  • 54. AST and Compilation ▣ AST: Abstract Syntax Tree ▣ During compilation the AST is transformed ▣ Hook into different phases to change the final byte-code. ▣ Initialization, Parsing, Conversion, Semantic analysis, Canonicalization, Instruction selection, Class generation, Output, Finalization.
  • 55. Groovy AST Transformations ▣ Groovy provides out-of-the-box a lot of AST Transformations ▣ @EqualsAndHashCode, @ToString, @TuppleConstructor, @Canonical, @Grab, @Immutable, @Delegate, @Singleton, @Category, @Log4j, @CompileStatic, @TypeChecked, @Synchronized, etc.
  • 56. Global AST Transformations ▣ There's no need to annotate anything. ▣ Applied to every single source unit during compilation. ▣ Can be applied to any phase in the compilation. ▣ Need a metadata file into the JAR file ▣ (META- INF/services/org.codehaus.groovy.transform. ASTTransformation) ▣ Grails uses Global Transformations intensively for example in GORM.
  • 57. Local AST Transformations ▣ Annotate the code and only applied to that code. ▣ Easy to debug. ▣ No need to create metadata file in a jar. ▣ Steps: Define an interface, Define the AST transformation, Enjoy!
  • 58. Why we should use MetaProgramming?
  • 59. Concept Review ▣ Metaprogramming Easy and very out-of-the box ▣ Easy and very powerful ▣ Write better code ▣ Add Behaviour easily ▣ Take advantage of this power because Groovy, it’s Groovy
  • 61. Thanks! Any questions? You can find us at - ▣ ali.tanwir@nexthoughts.com ▣ gaurav.gupta@nexthoughts.com You can find demo code used with this presentation at - https://github.com/NexThoughts/groovyMetaProgrammin g