SlideShare a Scribd company logo
1 of 45
Download to read offline
@aalmiray | andresalmiray.com
Andres
Almiray
Seasoned Sourceror

@ Oracle

Apache Groovy PMC

Java Champion

Hackergarten

github.com/aalmiray
Hot Releases!
3.0.6
4.0.0-alpha-1
@aalmiray | andresalmiray.com
https://en.wikipedia.org/wiki/Metaprogramming
Metaprogramming is a programming technique in which
computer programs have the ability to treat other programs
as their data. 

It means that a program can be designed to read, generate,
analyze or transform other programs, and even modify itself
while running. 

In some cases, this allows programmers to minimize the
number of lines of code to express a solution, in turn
reducing development time. It also allows programs greater
flexibility to efficiently handle new situations without
recompilation.
M.O.P.
@aalmiray | andresalmiray.com
Meta Object Protocol
• Every Class has a companion Metaclass 

• Metaclasses provide additional behavior such as

• Properties

• Methods

• Modifications are visible only to Groovy.
Enhancing a Groovy class
1 class Person {
2 String name
3 }
4
5 Person.metaClass.greet = { s ->
6 "Hello $s, my name is $name"
7 }
8
9 p = new Person(name: 'Andres')
10 p.greet('Groovy')
11
12 // Hello Groovy, my name is Andres
Enhancing a Java class
1 String.metaClass.spongeBob = {
2 int i = 0
3 delegate.toCharArray()collect { c ->
4 (i++ % 2 != 0) ? c : c.toUpperCase()
5 }.join('')
6 }
7
8 'Metaprogramming is fun'.spongeBob()
9
10 // MeTaPrOgRaMmInG Is fUn
DOES NOT UNDERSTAND
A catch-all option
1 class Foo {
2 Object methodMissing(String name, Object args) {
3 "What do you mean by ${name}(${args})?"
4 }
5 }
6
7 def foo = new Foo()
8 foo.say('Groovy')
9
10 // What do you mean by say([Groovy])?
A catch-all option
1 class Foo {
2 void propertyMissing(String name, Object arg) {
3 println "Can't assign a '$name' property to you!"
4 }
5
6 Object propertyMissing(String name) {
7 "You don't have a property named '$name'!"
8 }
9 }
10
11 def foo = new Foo()
12 println foo.id
13 foo.lang = 'Groovy'
14
15 // You don't have a property named 'id'!
16 // Can't assign a 'lang' property to you!
@aalmiray | andresalmiray.com
Does not Understand
• Method signatures must match the convention

• Object methodMissing(String, Object)

• void propertyMissing(String, Object)

• Object propertyMissing(String)

• May be implemented by both Groovy and Java classes
Categories
1 class Greeter {
2 static String greet(String self) {
3 "Hello ${self}!"
4 }
5 }
6
7 use(Greeter) {
8 'Groovy'.greet()
9 }
10
11 // Hello Groovy!
Categories
1 @Grab('org.apache.commons:commons-lang3:3.11')
2 import org.apache.commons.lang3.StringUtils
3
4 use(StringUtils) {
5 'Groovy'.chop() == 'Groov'
6 }
@aalmiray | andresalmiray.com
Categories
• Affect classes inside a specific scope.

• Methods must be static.

• Type of first argument becomes the receiver.
Mixins
1 @Grab('org.apache.commons:commons-lang3:3.11')
2 import org.apache.commons.lang3.StringUtils
3
4 class Greeter {
5 static String greet(String self) {
6 "Hello ${self}!"
7 }
8 }
9
10 String.mixin Greeter, StringUtils
11
12 'Groovy'.greet()
13 'Groovy'.chop()
14
15 // Hello Groovy!
16 // Groov
@aalmiray | andresalmiray.com
Mixins
• Like categories but their scope is not limited.

• Applies to both Groovy and Java classes.
Traits
1 interface NameProvider {
2 String getName()
3 }
4
5 trait WithName implements NameProvider {
6 String name
7 }
8
9 class Person implements WithName { }
10
11 String greet(NameProvider np) {
12 "Hello $np.name"
13 }
14
15 p = new Person(name: 'Groovy')
16 greet(p)
17
18 // Hello Groovy
@aalmiray | andresalmiray.com
Traits
• Java 8 gave us default methods on interfaces

• Groovy gives you that plus a stateful option
@aalmiray | andresalmiray.com
Extension Modules
• Like mixins but they are globally available.

• Can modify Groovy and Java classes.

• Provide instance and static methods.

• Can be type checked by the compiler.

• Require an additional resource (module descriptor).
Extension
1 package griffon.plugins.bcrypt;
2
3 public class BCryptExtension {
4 public static String encodeAsBcrypt(String self) {
5 return BCrypt.hashpw(self, BCrypt.gensalt());
6 }
7
8 public static String encodeAsBcrypt(String self, int
9 genSaltRound) {
10 return BCrypt.hashpw(self, BCrypt.gensalt(genSaltRound));
11 }
12 }
/META-INF/groovy/
org.codehaus.groovy.runtime.ExtensionModule
1 moduleName=griffon-bcrypt
2 moduleVersion=0.1
3 extensionClasses=griffon.plugins.bcrypt.BCryptExtension
4 staticExtensionClasses=
Using the Extension
1 String password = "my password"
2 // should give you a nice bcrypt hash
3 println password.encodeAsBcrypt()
@aalmiray | andresalmiray.com
Compile Time
• Modify the generated byte code.

• Modifications are visible to Groovy and Java classes.

• Modifications can be type checked by the compiler.
@aalmiray | andresalmiray.com
AST Xforms
• Two flavors:

• Local

• Global

• Writing your own requires knowledge of compiler APIs,
AST type hierarchy, Groovy internals, your standard dark
magic ;-)
@aalmiray | andresalmiray.com
Local AST Xforms
• Require two types:

• An interface that defines the entry point.

• An AST forms that’s linked to the interface.
@ToString
1 @groovy.transform.ToString
2 class Person {
3 String firstName
4 String lastName
5 }
6
7 p = new Person(firstName: 'Jack', lastName: 'Nicholson')
8
9 // Person(Jack, Nicholson)
@ToString
1 @java.lang.annotation.Documented
2 @Retention(RetentionPolicy.RUNTIME)
3 @Target({ElementType.TYPE})
4 @GroovyASTTransformationClass("org.codehaus.groovy.transform.
5 ToStringASTTransformation")
6 public @interface ToString {
7 ...
8 }
@ToString
1 @GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
2 public class ToStringASTTransformation
3 extends AbstractASTTransformation {
4 public void visit(ASTNode[] nodes, SourceUnit source) {
5 // magic goes here
6 }
7 }
@Canonical
1 @groovy.transform.Canonical
2 class Person {
3 String firstName
4 String lastName
5 }
6 def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson')
7 // Effect of @ToString
8 assert p1.toString() == 'Person(Jack, Nicholson)'
9
10 // Effect of @TupleConstructor
11 def p2 = new Person('Jack','Nicholson')
12 assert p2.toString() == 'Person(Jack, Nicholson)'
13
14 // Effect of @EqualsAndHashCode
15 assert p1==p2
16 // Effect of @EqualsAndHashCode
17 assert p1.hashCode()==p2.hashCode()
@Category
1 @groovy.lang.Category(String)
2 class Greeter {
3 String greet() {
4 "Hello ${this}!"
5 }
6 }
7
8 use(Greeter) {
9 'Groovy'.greet()
10 }
11
12 // Hello Groovy!
@Immutable
1 @groovy.transform.Immutable
2 class Point {
3 int x, y
4 }
5
6 p1 = new Point(10, 10)
7 p2 = new Point(x: 10, y: 10)
8 p3 = new Point(10, 20)
9
10 assert p1 == p2
11 assert p1 != p3
@Sortable
1 @groovy.transform.Sortable
2 class Thing {
3 String id
4 }
5
6 t1 = new Thing(id: '123')
7 t2 = new Thing(id: '456')
8
9 assert t1 < t2
@aalmiray | andresalmiray.com
70+ xforms available
@ASTTest @AnnotationCollector @AnnotationCollectorMode @AutoClone
@AutoCloneStyle @AutoExternalize @AutoFinal @AutoImplement @BaseScript
@Bindable @Canonical @Categoy @Commons @CompilationUnitAware
@CompileDynamic @CompileStatic @ConditionalInterrupt @Delegate
@EqualsAndHashCode @ExternalizeMethods @ExternalizeVerifier @Field
@Generated @Grab @GrabConfig @GrabExclude @GrabResolver @Grapes
@Immutable @ImmutableBase @ImmutableOptions @IndexedProperty
@InheritConstructors @Internal @KnownImmutable @Lazy @ListenerList @Log
@Log4j @Log4j2 @Macro @MapConstructor @Memoized @Mixin @NamedDelegate
@NamedParam @NamedParams @NamedVariant @Newify @NullCheck
@PackageScope @PackageScopeTarget @PlatformLog @PropertyOptions
@RecordBase @RecordType @SelfType @Singleton @Slf4j @Sortable @SourceURI
@Synchronized @TailRecursive @ThreadInterrupt @TimedInterrupt @ToString @Trait
@TupleConstructor @TypeChecked @TypeCheckingMode @Undefined @Vetoable
@VisibilityOptions @WithReadLock @WithWriteLock
@aalmiray | andresalmiray.com
Global AST Xforms
• They only require the AST xform implementation.

• They are always available to all classes during the
compilation step.
http://spockframework.org/
@aalmiray | andresalmiray.com
Implementing AST Xforms
• Use of compiler APIs such as Expression, Statement,
ClassNode, etc.

• May use ASTBuilder to create expressions and
statements from text, code, builder nodes.

• May use macro methods to simplify expressions.

• Refer to core AST forms for hints and tricks.
@aalmiray | andresalmiray.com
Resources
• https://groovy-lang.org/metaprogramming.html

• https://www.slideshare.net/paulk_asert/groovy-transforms

• A History of the Groovy Programming Language

• (https://dl.acm.org/doi/pdf/10.1145/3386326)
@aalmiray | andresalmiray.com

More Related Content

What's hot

Play Framework: The Basics
Play Framework: The BasicsPlay Framework: The Basics
Play Framework: The Basics
Philip Langer
 

What's hot (20)

Web application development using Play Framework (with Java)
Web application development using Play Framework (with Java)Web application development using Play Framework (with Java)
Web application development using Play Framework (with Java)
 
All the Laravel things: up and running to making $$
All the Laravel things: up and running to making $$All the Laravel things: up and running to making $$
All the Laravel things: up and running to making $$
 
FITC - Here Be Dragons: Advanced JavaScript Debugging
FITC - Here Be Dragons: Advanced JavaScript DebuggingFITC - Here Be Dragons: Advanced JavaScript Debugging
FITC - Here Be Dragons: Advanced JavaScript Debugging
 
An Introduction to the Laravel Framework (AFUP Forum PHP 2014)
An Introduction to the Laravel Framework (AFUP Forum PHP 2014)An Introduction to the Laravel Framework (AFUP Forum PHP 2014)
An Introduction to the Laravel Framework (AFUP Forum PHP 2014)
 
Play Framework and Activator
Play Framework and ActivatorPlay Framework and Activator
Play Framework and Activator
 
Intro to Laravel
Intro to LaravelIntro to Laravel
Intro to Laravel
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
 
Laravel Introduction
Laravel IntroductionLaravel Introduction
Laravel Introduction
 
CollabSphere 2018 - Java in Domino After XPages
CollabSphere 2018 - Java in Domino After XPagesCollabSphere 2018 - Java in Domino After XPages
CollabSphere 2018 - Java in Domino After XPages
 
Preparing for java 9 modules upload
Preparing for java 9 modules uploadPreparing for java 9 modules upload
Preparing for java 9 modules upload
 
Laravel
LaravelLaravel
Laravel
 
Introduction in the play framework
Introduction in the play frameworkIntroduction in the play framework
Introduction in the play framework
 
Learning Maven by Example
Learning Maven by ExampleLearning Maven by Example
Learning Maven by Example
 
Develop realtime web with Scala and Xitrum
Develop realtime web with Scala and XitrumDevelop realtime web with Scala and Xitrum
Develop realtime web with Scala and Xitrum
 
Play Framework: The Basics
Play Framework: The BasicsPlay Framework: The Basics
Play Framework: The Basics
 
Projects In Laravel : Learn Laravel Building 10 Projects
Projects In Laravel : Learn Laravel Building 10 ProjectsProjects In Laravel : Learn Laravel Building 10 Projects
Projects In Laravel : Learn Laravel Building 10 Projects
 
Maven tutorial
Maven tutorialMaven tutorial
Maven tutorial
 
What's New in Laravel 5 (Laravel Meetup - 23th Apr 15, Yogyakarta, ID)
What's New in Laravel 5 (Laravel Meetup - 23th Apr 15, Yogyakarta, ID)What's New in Laravel 5 (Laravel Meetup - 23th Apr 15, Yogyakarta, ID)
What's New in Laravel 5 (Laravel Meetup - 23th Apr 15, Yogyakarta, ID)
 
Play framework
Play frameworkPlay framework
Play framework
 
Faster java ee builds with gradle [con4921]
Faster java ee builds with gradle [con4921]Faster java ee builds with gradle [con4921]
Faster java ee builds with gradle [con4921]
 

Similar to Apache Groovy's Metaprogramming Options and You

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
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
Iftekhar Eather
 

Similar to Apache Groovy's Metaprogramming Options and You (20)

Oscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast LaneOscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast Lane
 
Apache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystemApache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystem
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy Plugins
 
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume LaforgeGroovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
 
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...
 
Introduction to Groovy runtime metaprogramming and AST transforms
Introduction to Groovy runtime metaprogramming and AST transformsIntroduction to Groovy runtime metaprogramming and AST transforms
Introduction to Groovy runtime metaprogramming and AST transforms
 
2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws
 
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?
 
An Introduction to Groovy for Java Developers
An Introduction to Groovy for Java DevelopersAn Introduction to Groovy for Java Developers
An Introduction to Groovy for Java Developers
 
Infinum android talks_10_getting groovy on android
Infinum android talks_10_getting groovy on androidInfinum android talks_10_getting groovy on android
Infinum android talks_10_getting groovy on android
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with Groovy
 
MetaProgramming with Groovy
MetaProgramming with GroovyMetaProgramming with Groovy
MetaProgramming with Groovy
 
Groovy 2 and beyond
Groovy 2 and beyondGroovy 2 and beyond
Groovy 2 and beyond
 
Grooscript greach 2015
Grooscript greach 2015Grooscript greach 2015
Grooscript greach 2015
 
Grooscript gr8conf
Grooscript gr8confGrooscript gr8conf
Grooscript gr8conf
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
 
Groovy Metaprogramming for Dummies
Groovy Metaprogramming for DummiesGroovy Metaprogramming for Dummies
Groovy Metaprogramming for Dummies
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
Groovy & Grails: Scripting for Modern Web Applications
Groovy & Grails: Scripting for Modern Web ApplicationsGroovy & Grails: Scripting for Modern Web Applications
Groovy & Grails: Scripting for Modern Web Applications
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
 

More from Andres Almiray

More from Andres Almiray (20)

Creando, creciendo, y manteniendo una comunidad de codigo abierto
Creando, creciendo, y manteniendo una comunidad de codigo abiertoCreando, creciendo, y manteniendo una comunidad de codigo abierto
Creando, creciendo, y manteniendo una comunidad de codigo abierto
 
Liberando a produccion con confianza
Liberando a produccion con confianzaLiberando a produccion con confianza
Liberando a produccion con confianza
 
Liberando a produccion con confidencia
Liberando a produccion con confidenciaLiberando a produccion con confidencia
Liberando a produccion con confidencia
 
OracleDB Ecosystem for Java Developers
OracleDB Ecosystem for Java DevelopersOracleDB Ecosystem for Java Developers
OracleDB Ecosystem for Java Developers
 
Softcon.ph - Maven Puzzlers
Softcon.ph - Maven PuzzlersSoftcon.ph - Maven Puzzlers
Softcon.ph - Maven Puzzlers
 
Maven Puzzlers
Maven PuzzlersMaven Puzzlers
Maven Puzzlers
 
Oracle Database Ecosystem for Java Developers
Oracle Database Ecosystem for Java DevelopersOracle Database Ecosystem for Java Developers
Oracle Database Ecosystem for Java Developers
 
JReleaser - Releasing at the speed of light
JReleaser - Releasing at the speed of lightJReleaser - Releasing at the speed of light
JReleaser - Releasing at the speed of light
 
Going Reactive with g rpc
Going Reactive with g rpcGoing Reactive with g rpc
Going Reactive with g rpc
 
What I wish I knew about Maven years ago
What I wish I knew about Maven years agoWhat I wish I knew about Maven years ago
What I wish I knew about Maven years ago
 
The impact of sci fi in tech
The impact of sci fi in techThe impact of sci fi in tech
The impact of sci fi in tech
 
Gradle Ex Machina - Devoxx 2019
Gradle Ex Machina - Devoxx 2019Gradle Ex Machina - Devoxx 2019
Gradle Ex Machina - Devoxx 2019
 
Interacting with the Oracle Cloud Java SDK with Gradle
Interacting with the Oracle Cloud Java SDK with GradleInteracting with the Oracle Cloud Java SDK with Gradle
Interacting with the Oracle Cloud Java SDK with Gradle
 
Gradle ex-machina
Gradle ex-machinaGradle ex-machina
Gradle ex-machina
 
Go Java, Go!
Go Java, Go!Go Java, Go!
Go Java, Go!
 
Going Reactive with gRPC
Going Reactive with gRPCGoing Reactive with gRPC
Going Reactive with gRPC
 
The JavaFX Ecosystem
The JavaFX EcosystemThe JavaFX Ecosystem
The JavaFX Ecosystem
 
Understanding Reactive Programming
Understanding Reactive ProgrammingUnderstanding Reactive Programming
Understanding Reactive Programming
 
Spock's New Tricks
Spock's New TricksSpock's New Tricks
Spock's New Tricks
 
Go Java, Go!
Go Java, Go!Go Java, Go!
Go Java, Go!
 

Recently uploaded

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Recently uploaded (20)

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 

Apache Groovy's Metaprogramming Options and You

  • 1.
  • 2. @aalmiray | andresalmiray.com Andres Almiray Seasoned Sourceror @ Oracle Apache Groovy PMC Java Champion Hackergarten github.com/aalmiray
  • 4. @aalmiray | andresalmiray.com https://en.wikipedia.org/wiki/Metaprogramming Metaprogramming is a programming technique in which computer programs have the ability to treat other programs as their data. It means that a program can be designed to read, generate, analyze or transform other programs, and even modify itself while running. In some cases, this allows programmers to minimize the number of lines of code to express a solution, in turn reducing development time. It also allows programs greater flexibility to efficiently handle new situations without recompilation.
  • 5.
  • 6.
  • 8. @aalmiray | andresalmiray.com Meta Object Protocol • Every Class has a companion Metaclass • Metaclasses provide additional behavior such as • Properties • Methods • Modifications are visible only to Groovy.
  • 9. Enhancing a Groovy class 1 class Person { 2 String name 3 } 4 5 Person.metaClass.greet = { s -> 6 "Hello $s, my name is $name" 7 } 8 9 p = new Person(name: 'Andres') 10 p.greet('Groovy') 11 12 // Hello Groovy, my name is Andres
  • 10. Enhancing a Java class 1 String.metaClass.spongeBob = { 2 int i = 0 3 delegate.toCharArray()collect { c -> 4 (i++ % 2 != 0) ? c : c.toUpperCase() 5 }.join('') 6 } 7 8 'Metaprogramming is fun'.spongeBob() 9 10 // MeTaPrOgRaMmInG Is fUn
  • 12. A catch-all option 1 class Foo { 2 Object methodMissing(String name, Object args) { 3 "What do you mean by ${name}(${args})?" 4 } 5 } 6 7 def foo = new Foo() 8 foo.say('Groovy') 9 10 // What do you mean by say([Groovy])?
  • 13. A catch-all option 1 class Foo { 2 void propertyMissing(String name, Object arg) { 3 println "Can't assign a '$name' property to you!" 4 } 5 6 Object propertyMissing(String name) { 7 "You don't have a property named '$name'!" 8 } 9 } 10 11 def foo = new Foo() 12 println foo.id 13 foo.lang = 'Groovy' 14 15 // You don't have a property named 'id'! 16 // Can't assign a 'lang' property to you!
  • 14. @aalmiray | andresalmiray.com Does not Understand • Method signatures must match the convention • Object methodMissing(String, Object) • void propertyMissing(String, Object) • Object propertyMissing(String) • May be implemented by both Groovy and Java classes
  • 15. Categories 1 class Greeter { 2 static String greet(String self) { 3 "Hello ${self}!" 4 } 5 } 6 7 use(Greeter) { 8 'Groovy'.greet() 9 } 10 11 // Hello Groovy!
  • 16. Categories 1 @Grab('org.apache.commons:commons-lang3:3.11') 2 import org.apache.commons.lang3.StringUtils 3 4 use(StringUtils) { 5 'Groovy'.chop() == 'Groov' 6 }
  • 17. @aalmiray | andresalmiray.com Categories • Affect classes inside a specific scope. • Methods must be static. • Type of first argument becomes the receiver.
  • 18. Mixins 1 @Grab('org.apache.commons:commons-lang3:3.11') 2 import org.apache.commons.lang3.StringUtils 3 4 class Greeter { 5 static String greet(String self) { 6 "Hello ${self}!" 7 } 8 } 9 10 String.mixin Greeter, StringUtils 11 12 'Groovy'.greet() 13 'Groovy'.chop() 14 15 // Hello Groovy! 16 // Groov
  • 19. @aalmiray | andresalmiray.com Mixins • Like categories but their scope is not limited. • Applies to both Groovy and Java classes.
  • 20. Traits 1 interface NameProvider { 2 String getName() 3 } 4 5 trait WithName implements NameProvider { 6 String name 7 } 8 9 class Person implements WithName { } 10 11 String greet(NameProvider np) { 12 "Hello $np.name" 13 } 14 15 p = new Person(name: 'Groovy') 16 greet(p) 17 18 // Hello Groovy
  • 21. @aalmiray | andresalmiray.com Traits • Java 8 gave us default methods on interfaces • Groovy gives you that plus a stateful option
  • 22. @aalmiray | andresalmiray.com Extension Modules • Like mixins but they are globally available. • Can modify Groovy and Java classes. • Provide instance and static methods. • Can be type checked by the compiler. • Require an additional resource (module descriptor).
  • 23. Extension 1 package griffon.plugins.bcrypt; 2 3 public class BCryptExtension { 4 public static String encodeAsBcrypt(String self) { 5 return BCrypt.hashpw(self, BCrypt.gensalt()); 6 } 7 8 public static String encodeAsBcrypt(String self, int 9 genSaltRound) { 10 return BCrypt.hashpw(self, BCrypt.gensalt(genSaltRound)); 11 } 12 }
  • 24. /META-INF/groovy/ org.codehaus.groovy.runtime.ExtensionModule 1 moduleName=griffon-bcrypt 2 moduleVersion=0.1 3 extensionClasses=griffon.plugins.bcrypt.BCryptExtension 4 staticExtensionClasses=
  • 25. Using the Extension 1 String password = "my password" 2 // should give you a nice bcrypt hash 3 println password.encodeAsBcrypt()
  • 26.
  • 27. @aalmiray | andresalmiray.com Compile Time • Modify the generated byte code. • Modifications are visible to Groovy and Java classes. • Modifications can be type checked by the compiler.
  • 28.
  • 29.
  • 30. @aalmiray | andresalmiray.com AST Xforms • Two flavors: • Local • Global • Writing your own requires knowledge of compiler APIs, AST type hierarchy, Groovy internals, your standard dark magic ;-)
  • 31. @aalmiray | andresalmiray.com Local AST Xforms • Require two types: • An interface that defines the entry point. • An AST forms that’s linked to the interface.
  • 32. @ToString 1 @groovy.transform.ToString 2 class Person { 3 String firstName 4 String lastName 5 } 6 7 p = new Person(firstName: 'Jack', lastName: 'Nicholson') 8 9 // Person(Jack, Nicholson)
  • 33. @ToString 1 @java.lang.annotation.Documented 2 @Retention(RetentionPolicy.RUNTIME) 3 @Target({ElementType.TYPE}) 4 @GroovyASTTransformationClass("org.codehaus.groovy.transform. 5 ToStringASTTransformation") 6 public @interface ToString { 7 ... 8 }
  • 34. @ToString 1 @GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION) 2 public class ToStringASTTransformation 3 extends AbstractASTTransformation { 4 public void visit(ASTNode[] nodes, SourceUnit source) { 5 // magic goes here 6 } 7 }
  • 35. @Canonical 1 @groovy.transform.Canonical 2 class Person { 3 String firstName 4 String lastName 5 } 6 def p1 = new Person(firstName: 'Jack', lastName: 'Nicholson') 7 // Effect of @ToString 8 assert p1.toString() == 'Person(Jack, Nicholson)' 9 10 // Effect of @TupleConstructor 11 def p2 = new Person('Jack','Nicholson') 12 assert p2.toString() == 'Person(Jack, Nicholson)' 13 14 // Effect of @EqualsAndHashCode 15 assert p1==p2 16 // Effect of @EqualsAndHashCode 17 assert p1.hashCode()==p2.hashCode()
  • 36. @Category 1 @groovy.lang.Category(String) 2 class Greeter { 3 String greet() { 4 "Hello ${this}!" 5 } 6 } 7 8 use(Greeter) { 9 'Groovy'.greet() 10 } 11 12 // Hello Groovy!
  • 37. @Immutable 1 @groovy.transform.Immutable 2 class Point { 3 int x, y 4 } 5 6 p1 = new Point(10, 10) 7 p2 = new Point(x: 10, y: 10) 8 p3 = new Point(10, 20) 9 10 assert p1 == p2 11 assert p1 != p3
  • 38. @Sortable 1 @groovy.transform.Sortable 2 class Thing { 3 String id 4 } 5 6 t1 = new Thing(id: '123') 7 t2 = new Thing(id: '456') 8 9 assert t1 < t2
  • 39. @aalmiray | andresalmiray.com 70+ xforms available @ASTTest @AnnotationCollector @AnnotationCollectorMode @AutoClone @AutoCloneStyle @AutoExternalize @AutoFinal @AutoImplement @BaseScript @Bindable @Canonical @Categoy @Commons @CompilationUnitAware @CompileDynamic @CompileStatic @ConditionalInterrupt @Delegate @EqualsAndHashCode @ExternalizeMethods @ExternalizeVerifier @Field @Generated @Grab @GrabConfig @GrabExclude @GrabResolver @Grapes @Immutable @ImmutableBase @ImmutableOptions @IndexedProperty @InheritConstructors @Internal @KnownImmutable @Lazy @ListenerList @Log @Log4j @Log4j2 @Macro @MapConstructor @Memoized @Mixin @NamedDelegate @NamedParam @NamedParams @NamedVariant @Newify @NullCheck @PackageScope @PackageScopeTarget @PlatformLog @PropertyOptions @RecordBase @RecordType @SelfType @Singleton @Slf4j @Sortable @SourceURI @Synchronized @TailRecursive @ThreadInterrupt @TimedInterrupt @ToString @Trait @TupleConstructor @TypeChecked @TypeCheckingMode @Undefined @Vetoable @VisibilityOptions @WithReadLock @WithWriteLock
  • 40. @aalmiray | andresalmiray.com Global AST Xforms • They only require the AST xform implementation. • They are always available to all classes during the compilation step.
  • 42. @aalmiray | andresalmiray.com Implementing AST Xforms • Use of compiler APIs such as Expression, Statement, ClassNode, etc. • May use ASTBuilder to create expressions and statements from text, code, builder nodes. • May use macro methods to simplify expressions. • Refer to core AST forms for hints and tricks.
  • 43. @aalmiray | andresalmiray.com Resources • https://groovy-lang.org/metaprogramming.html • https://www.slideshare.net/paulk_asert/groovy-transforms • A History of the Groovy Programming Language • (https://dl.acm.org/doi/pdf/10.1145/3386326)
  • 44.