greach 2014 - metaprogramming with groovy

54
IvAn LOpez MartIn @ilopmar Metaprogramming with Groovy

Upload: ivan-lopez

Post on 10-May-2015

4.039 views

Category:

Technology


2 download

DESCRIPTION

Slides from my talk at Greach 2014: "Groovy is a dynamic language that provides different types of metaprogramming techniques. In this talk we’ll mainly see runtime metaprogramming. I’ll explain Groovy Meta-Object-Protocol (MOP), the metaclass, how to intercept method calls, how to deal with method missing and property missing, the use of mixins and categories. All of these topics will be explained with examples in order to understand them. Also, I’ll talk a little bit about compile-time metaprogramming with AST Transformations. AST Transformations provide a wonderful way of manipulating code at compile time via modifications of the Abstract Syntax Tree. We’ll see a basic but powerful example of what we can do with AST transformations." The code is available at: https://github.com/lmivan/greach2014

TRANSCRIPT

Page 1: Greach 2014 - Metaprogramming with groovy

IvAn LOpez MartIn @ilopmar

Metaprogramming with Groovy

Page 2: Greach 2014 - Metaprogramming with groovy

Iván Lopez Martín @ilopmar

I work at Kaleidos

Using Groovy/Grails since 4 years

Creator of www.bokzuy.com

Developed some Grails plugins: Postgreslq-Extensions, Slug-Generator, Ducksboard-API,...

Usual Suspect of Madrid-GUG (Groovy User Group)

Who am I?

2/54

Page 3: Greach 2014 - Metaprogramming with groovy

- A dynamic language like Groovy allows to "delay" to runtime some checks that are usually performed during the compilation.

- Add new properties, methods and behaviour during 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.

Groovy is Dynamic

3/54

Page 4: Greach 2014 - Metaprogramming with groovy

What is Metaprogramming?

Page 5: Greach 2014 - Metaprogramming with groovy

From Wikipedia:

Metaprogramming is the writing of computer programs that write or manipulate other programs (or themselves) as their data, or that do part of the work at compile time that would otherwise be done at runtime.

“Writing code that writes code”

What is Metaprogramming?

5/54

Page 6: Greach 2014 - Metaprogramming with groovy

RuntimeMetaprogramming

Page 7: Greach 2014 - Metaprogramming with groovy

- Groovy provides this capability through the Meta-Object Protocol (MOP).

- We can use MOP to invoke methods dynamically and also synthesize classes and methods on the fly.

Runtime Metaprogramming

7/54

Page 8: Greach 2014 - Metaprogramming with groovy

Groovy

Groovy

Java

Java

MOP

What is the Meta Object Protocol (MOP)?

8/54

Page 9: Greach 2014 - Metaprogramming with groovy

Intercepting methodsusing MOP

Page 10: Greach 2014 - Metaprogramming with groovy

- Classes compiled by Groovy implements GroovyObject interface.

- We can implement GroovyInterceptable to hook into the execution process.

- When implementing invokeMethod(), it is called for every method (existing and nonexisting).

Groovy Interceptable

10/54

Page 11: Greach 2014 - Metaprogramming with groovy

GroovyInterceptable example

11/54

Page 12: Greach 2014 - Metaprogramming with groovy

GroovyInterceptable example (II)

12/54

Page 13: Greach 2014 - Metaprogramming with groovy

- 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.

Intercepting methods using MetaClass

13/54

Page 14: Greach 2014 - Metaprogramming with groovy

MetaClass example

14/54

Page 15: Greach 2014 - Metaprogramming with groovy

MOPMethod Injection

Page 16: Greach 2014 - Metaprogramming with groovy

- In Groovy we can “open” a class at any time.

- Method Injection at code-writing time, we know the names of methods we want to add.

- Different techniques: - MetaClass - Categories - Extensions - Mixins

MOP Method Injection

16/54

Page 17: Greach 2014 - Metaprogramming with groovy

- 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.

- ProxyMetaClass: Can decorate a meta class with interception capabilities.

- Other meta classes used internally and for testing.

MetaClass

17/54

Page 18: Greach 2014 - Metaprogramming with groovy

Adding methods using MetaClass

18/54

Page 19: Greach 2014 - Metaprogramming with groovy

Adding properties using MetaClass

19/54

* Note: This is only true for Groovy. In Grails all MetaClass are ExpandoMetaClass.

Thank you Burt Beckwith for the clarification

Page 20: Greach 2014 - Metaprogramming with groovy

Adding constructor using MetaClass

20/54

Page 21: Greach 2014 - Metaprogramming with groovy

Overriding methods using MetaClass

21/54

Page 22: Greach 2014 - Metaprogramming with groovy

Overriding methods using MetaClass

22/54

Page 23: Greach 2014 - Metaprogramming with groovy

- 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 is reset to its old state.

- Category classes are no special.

Categories

23/54

Page 24: Greach 2014 - Metaprogramming with groovy

Categories example

Page 25: Greach 2014 - Metaprogramming with groovy

Categories example (II)

25/54

Page 26: Greach 2014 - Metaprogramming with groovy

Categories example (II)

26/54

Page 27: Greach 2014 - Metaprogramming with groovy

Categories example (II)

27/54

Page 28: Greach 2014 - Metaprogramming with groovy

- JAR file with classes that provide extra methods to other classes.

- It also has to contain a meta-information file

- Add the JAR to the classpath to enhance the classes.

- The extension methods needs to be public and static.

Extension modules

28/54

Page 29: Greach 2014 - Metaprogramming with groovy

Extension modules example

29/54

Page 30: Greach 2014 - Metaprogramming with groovy

- 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.

Mixins

30/54

Page 31: Greach 2014 - Metaprogramming with groovy

Mixins example

31/54

Page 32: Greach 2014 - Metaprogramming with groovy

MOP Method Synthesis

Page 33: Greach 2014 - Metaprogramming with groovy

- 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.

MOP Method Synthesis

33/54

Page 34: Greach 2014 - Metaprogramming with groovy

Check for methods and properties

34/54

Page 35: Greach 2014 - Metaprogramming with groovy

MOP Instances Synthesis

35/54

Page 36: Greach 2014 - Metaprogramming with groovy

MethodMissing example

36/54

Page 37: Greach 2014 - Metaprogramming with groovy

MethodMissing example

37/54

Page 38: Greach 2014 - Metaprogramming with groovy

MethodMissing example

38/54

Page 39: Greach 2014 - Metaprogramming with groovy

Compile-timeMetaprogramming

Page 40: Greach 2014 - Metaprogramming with groovy

- 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 operationsall without explicitly modifying the source code.

- We write code that generates bytecode or gets involved during the bytecode generation.

Compile-time Metaprogramming

40/54

Page 41: Greach 2014 - Metaprogramming with groovy

- 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.

AST and Compilation

41/54

Page 42: Greach 2014 - Metaprogramming with groovy

- Groovy provides out-of-the-box a lot of AST Transformations

- @EqualsAndHashCode, @ToString, @TuppleConstructor, @Canonical, @Grab, @Immutable, @Delegate, @Singleton, @Category, @Log4j, @CompileStatic, @TypeChecked, @Synchronized...

Groovy AST Transformations

42/54

Page 43: Greach 2014 - Metaprogramming with groovy

Global AST Transformations

Page 44: Greach 2014 - Metaprogramming with groovy

- 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.

Global AST Transformations

44/54

Page 45: Greach 2014 - Metaprogramming with groovy

LocalAST Transformations

Page 46: Greach 2014 - Metaprogramming with groovy

- 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!

Local AST Transformations

46/54

Page 47: Greach 2014 - Metaprogramming with groovy

Local AST Transformation example

47/54

Page 48: Greach 2014 - Metaprogramming with groovy

Local AST Transformation example

Page 49: Greach 2014 - Metaprogramming with groovy

Local AST Transformation example

Page 50: Greach 2014 - Metaprogramming with groovy

- Most of us are not Groovy Commiters, so how do we create the necessary nodes for our AST Transformation.

- Check de documentation: http://groovy.codehaus.org/api/org/codehaus/groovy/ast/ASTNode.html

- Use an IDE

- Use GroovyConsole and open Groovy AST Browser (CTRL + T)

Creating AST nodes. What?

50/54

Page 51: Greach 2014 - Metaprogramming with groovy

- Yes. We can use AstBuilder

- buildFromSpec: Provides a DSL for the ClassNode objects

- buildFromString: Creates the AST nodes from a String with the code.

- buildFromCode: We write directly the source code and the builder returns the AST.

Is there an easy way?

51/54

Page 52: Greach 2014 - Metaprogramming with groovy

Recap:Why we should use all of this?

Page 53: Greach 2014 - Metaprogramming with groovy

- Groovy provides meta-programming features out-of-the-box, it's a pity not using them.

- Metaprogramming is easy to use and it's very powerful.

- We can write better code.

- We can add a lot of behaviour to our code in an easy way.

- We're Groovy developers and we need to take advantage of all its power.

- Because, Groovy it's groovy.

Why we should use all of this?

53/54

Page 54: Greach 2014 - Metaprogramming with groovy

http://lopezivan.blogspot.comhttp://lopezivan.blogspot.com

@ilopmar@ilopmar

https://github.com/lmivanhttps://github.com/lmivan

Iván López MartínIván López Martín

[email protected]@gmail.com

Talk Survey:Talk Survey:http://kcy.me/11lvbhttp://kcy.me/11lvb

Thank you!

http://kaleidos.net/4B0082http://kaleidos.net/4B0082