KEMBAR78
Greach 2014 - Metaprogramming with groovy | PDF
IvAn LOpez MartIn @ilopmar
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
- 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
What is
Metaprogramming?
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
Runtime
Metaprogramming
- 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
Groovy
Groovy
Java
Java
MOP
What is the Meta Object Protocol (MOP)?
8/54
Intercepting methods
using MOP
- 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
GroovyInterceptable example
11/54
GroovyInterceptable example (II)
12/54
- 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
MetaClass example
14/54
MOP
Method Injection
- 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
- 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
Adding methods using MetaClass
18/54
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
Adding constructor using MetaClass
20/54
Overriding methods using MetaClass
21/54
Overriding methods using MetaClass
22/54
- 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
Categories example
Categories example (II)
25/54
Categories example (II)
26/54
Categories example (II)
27/54
- 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
Extension modules example
29/54
- 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
Mixins example
31/54
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.
MOP Method Synthesis
33/54
Check for methods and properties
34/54
MOP Instances Synthesis
35/54
MethodMissing example
36/54
MethodMissing example
37/54
MethodMissing example
38/54
Compile-time
Metaprogramming
- Advanced feature.
- Analyze and modify a program’sstructure 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.
Compile-time Metaprogramming
40/54
- 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
- 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
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.
Global AST Transformations
44/54
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!
Local AST Transformations
46/54
Local AST Transformation example
47/54
Local AST Transformation example
Local AST Transformation example
- 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
- 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
Recap:
Why we should use
all of this?
- 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
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
lopez.ivan@gmail.comlopez.ivan@gmail.com
Talk Survey:Talk Survey:
http://kcy.me/11lvbhttp://kcy.me/11lvb
Thank you!
http://kaleidos.net/4B0082http://kaleidos.net/4B0082

Greach 2014 - Metaprogramming with groovy

  • 1.
    IvAn LOpez MartIn@ilopmar Metaprogramming with Groovy
  • 2.
    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
  • 3.
    - A dynamiclanguage 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
  • 4.
  • 5.
    From Wikipedia: Metaprogramming isthe 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
  • 6.
  • 7.
    - Groovy providesthis 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
  • 8.
    Groovy Groovy Java Java MOP What is theMeta Object Protocol (MOP)? 8/54
  • 9.
  • 10.
    - Classes compiledby 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
  • 11.
  • 12.
  • 13.
    - Groovy maintainsa 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
  • 14.
  • 15.
  • 16.
    - In Groovywe 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
  • 17.
    - MetaClassImpl: Defaultmeta 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
  • 18.
    Adding methods usingMetaClass 18/54
  • 19.
    Adding properties usingMetaClass 19/54 * Note: This is only true for Groovy. In Grails all MetaClass are ExpandoMetaClass. Thank you Burt Beckwith for the clarification
  • 20.
    Adding constructor usingMetaClass 20/54
  • 21.
    Overriding methods usingMetaClass 21/54
  • 22.
    Overriding methods usingMetaClass 22/54
  • 23.
    - Changes madeto 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
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
    - JAR filewith 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
  • 29.
  • 30.
    - A mixinallow “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
  • 31.
  • 32.
  • 33.
    - Dynamically figureout 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
  • 34.
    Check for methodsand properties 34/54
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
    - Advanced feature. -Analyze and modify a program’sstructure 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. Compile-time Metaprogramming 40/54
  • 41.
    - AST: AbstractSyntax 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
  • 42.
    - Groovy providesout-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
  • 43.
  • 44.
    - There's noneed 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
  • 45.
  • 46.
    - Annotate thecode 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
  • 47.
  • 48.
  • 49.
  • 50.
    - Most ofus 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
  • 51.
    - Yes. Wecan 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
  • 52.
    Recap: Why we shoulduse all of this?
  • 53.
    - Groovy providesmeta-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
  • 54.
    http://lopezivan.blogspot.comhttp://lopezivan.blogspot.com @ilopmar@ilopmar https://github.com/lmivanhttps://github.com/lmivan Iván López MartínIvánLópez Martín lopez.ivan@gmail.comlopez.ivan@gmail.com Talk Survey:Talk Survey: http://kcy.me/11lvbhttp://kcy.me/11lvb Thank you! http://kaleidos.net/4B0082http://kaleidos.net/4B0082