SlideShare una empresa de Scribd logo
1 de 88
Descargar para leer sin conexión
GROOVY 2.5+, 3.0
1
HEY HOLA
Name
Mario Garcia
Sigo trabajando en Kaleidos
https://kaleidos.net
2 . 1
ME
Sospechoso de pertenecer al:
Madrid Groovy User Group
Social:
https://twitter.com/marioggar
https://github.com/mariogarcia
2 . 2
QUE VENIA A CONTAROS ?
Groovy en numeros
Groovy roadmap 2018 / 2019
Que nos ofrece la version 2.5+
Que nos ofrece la version 3.0
3
GROOVY EN NUMEROS
4 . 1
REFERENCIAS
OCI Webminar 23, may 2018 by Paul King
Groovy distribution archive
4 . 2
CONTRIBUTORS
30+ nuevos contributors en los ultimos 16 meses
4 . 3
DESCARGAS
23 millones 2016
50 millones 2017
19 millones solo en el 1er Q de 2018
+ 4 millones de descargas al mes y subiendo
4 . 4
ULTIMAS VERSIONES
2.4.15: 2018-09-04
2.5.3: 2018-10-14
2.6.0-alpha-4: 2018-06-26
3.0.0-alpha-3: 2018-06-26
4 . 5
ROADMAP
5 . 1
GROOVY 2.5.X
La 2.5.x ya lleva con nosotros 5 meses (2018-05-30)
Actualizaciones a buen ritmo
2.5.0: mayo
2.5.1: julio
2.5.2: agosto
5 . 2
GROOVY 2.5.X (II)
Macros
JDK 7 es el minimo
Compatible con JDK9/10 con warnings
5 . 3
GROOVY 2.6, 3.0
Alphas de ambas desde mediados de 2018
Parrot parser (JDK8 syntax 1 - 1 y mucho mas)
2.6
JDK7 (min)
Corta esperanza de vida
5 . 4
HABLEMOS DE GROOVY 2.5
6
ANNOTATIONS
7 . 1
7 . 2
EN GENERAL
Flexibilidad en antiguas anotaciones
Conversion en Meta anotaciones
Validacion de parametros
Ayuda en la cobertura de codigo
7 . 3
EJEMPLOS
@Immutable
@AutoImplement
@AutoFinal
@NamedXXX
@Generated
7 . 4
@IMMUTABLE
No poder modificar los campos de una clase
Si los campos son otras clases…
Comprueba que sean immutables tambien
O que esten en una lista blanca de clases
7 . 5
@IMMUTABLE (OLD)
package madridgug.immutable
import groovy.transform.Immutable
@Immutable
class Car {
Brand brand (1)
String model
Double hp
Map<?, String> extra (2)
}
7 . 6
@IMMUTABLE (NEW - JAVA.TIME)
package madridgug.immutable
import java.time.LocalTime
import groovy.transform.Immutable
@Immutable
class Brand {
String name
LocalTime birthdate (1)
}
7 . 7
@IMMUTABLE (NEW - DI FRIENDLY)
package madridgug.immutable
import groovy.transform.Canonical
import groovy.transform.ImmutableBase
import groovy.transform.PropertyOptions
import groovy.transform.options.ImmutablePropertyHandler
@ImmutableBase
@Canonical(defaults = false)
@PropertyOptions(propertyHandler = ImmutablePropertyHandler)
class SecurityConfig {
URI provider
String key
}
7 . 8
@IMMUTABLE (DI FRIENDLY - II)
+ 1 vez ⇒ Meta anotacion
package madridgug.immutable
import groovy.transform.*
import groovy.transform.options.*
@ImmutableBase
@TupleConstructor(defaults = false)
@PropertyOptions(propertyHandler = ImmutablePropertyHandler)
@AnnotationCollector
@interface ImmutableDI {
}
7 . 9
@IMMUTABLE (DI FRIENDLY - III)
Annotated class
Google Guice Module
package madridgug.immutable
@ImmutableDI
class SecurityConfig2 {
URI provider
String key
}
def ctor = SecurityConfig2.getConstructor(URI, String)
bind(SecurityConfig2)
.toConstructor(ctor)
.in(Scopes.SINGLETON)
7 . 10
@IMMUTABLE (DI FRIENDLY - IV)
given: 'a Google Guice Injector'
Injector di = Guice.createInjector(new GuiceModule())
when: 'getting the configuration instance'
SecurityConfig2 config = di.getInstance(SecurityConfig2)
then: 'properties should've been populated properly'
config.key == 'key'
config.provider == URI.create('https://nowhereprovider.io')
when: 'trying to change properties again'
config.key = 'another key'
then: 'an error will be thrown'
thrown(ReadOnlyPropertyException)
7 . 11
@IMMUTABLE (OPTIONAL)
Considerado immutable tambien
package madridgug.immutable
import groovy.transform.Immutable
@Immutable
class Person {
String name
Integer age
Optional<String> mobile
}
7 . 12
@AUTOIMPLEMENT
A veces tenemos que implementar un interface
Pero no queremos / podemos implementarlo entero
7 . 13
@AUTOIMPLEMENT
package madridgug.autoimplement
interface MessageSender {
/**
* Sends a message {@link String}
*/
UUID sendMessage(String message)
/**
* Checks whether the message has been received yet or not
*/
boolean isMessageReceived(UUID messageId)
/**
* Checks whether the message has been sent yet or not
*/
Boolean isMessageSent(UUID messageId)
}
7 . 14
@AUTOIMPLEMENT
Default
package madridgug.autoimplement
import groovy.util.logging.Slf4j
import groovy.transform.AutoImplement
@Slf4j
@AutoImplement
class PartialMessageSender implements MessageSender {
@Override
UUID sendMessage(String message) {
log.info "message: $message"
return UUID.randomUUID()
}
}
7 . 15
@AUTOIMPLEMENT
Throw exceptions
package madridgug.autoimplement
import madridgug.exception.NotEnoughTimePalException
import groovy.util.logging.Slf4j
import groovy.transform.AutoImplement
@Slf4j
@AutoImplement(exception = NotEnoughTimePalException)
class NoisyMessageSender implements MessageSender {
@Override
UUID sendMessage(String message) {
log.info "message: $message"
return UUID.randomUUID()
}
7 . 16
@AUTOIMPLEMENT
Custom code
package madridgug.autoimplement
import static java.time.LocalDateTime.now
import groovy.util.logging.Slf4j
import groovy.transform.AutoImplement
@Slf4j
@AutoImplement(code = {
log.error("Necesito + tiempo ok? Prueba a las: ${now() + 120}")
})
class VeryNoisyMessageSender implements MessageSender {
}
7 . 17
@AUTOFINAL
A veces cometemos errores re-asignando una variable
Deberia avisarnos en tiempo de compilacion
7 . 18
@AUTOFINAL
package madridgug.autofinal
import groovy.transform.AutoFinal
class WordProcessor {
@AutoFinal
String reverseWord(Word word) {
// word = new Word(word: 'another') (1)
return word.reverse()
}
Integer size(Word word) {
word = new Word(word: 'another') (2)
return word.size()
}
7 . 19
@DELEGATE ENHANCEMENTS
Hasta ahora solo se podia utilizar sobre propiedades de la
clase
7 . 20
@DELEGATE ENHANCEMENTS
Ahora @Delegate se puede usar en getters
package madridgug.delegate
class TennisPlayer {
List<Map> wins
String name
@Delegate
Integer getWinSize() {
return wins.size()
}
}
7 . 21
@DELEGATE ENHANCEMENTS
given: 'two players'
def good = new TennisPlayer(name: 'John', wins: [
[name: 'Roland Garros 2014'],
[name: 'Roland Garros 2015'],
[name: 'Roland Garros 2016']
])
def bad = new TennisPlayer(name: 'Peter', wins: [
[name: 'Somewhere 2002']
])
and: 'the good one should be greater than the bad one'
good.intValue() > bad.intValue()
7 . 22
@NAMEDVARIANT
Posibilidad de llamar a un metodo con la instancia del
tipo requerido o …
Descomponiendo la instancia en sus diferentes attributos
7 . 23
@NAMEDVARIANT
package madridgug.namedvariant
class Car {
String brand
String model
Integer hp
}
package madridgug.namedvariant
import groovy.util.logging.Slf4j
import groovy.transform.NamedVariant
import groovy.transform.NamedDelegate
@Slf4j
class CarProcessor {
@NamedVariant
void process(@NamedDelegate Car car) {
log.info "processing: ${car.model}"
}
}
7 . 24
@NAMEDVARIANT
Pasando una instancia
Car car = new Car(brand: 'ferrari', model: 'F450', hp: 450)
CarProcessor processor = new CarProcessor()
when: 'processing the car'
processor.process(car)
7 . 25
@NAMEDVARIANT
Pasando propiedades
and: 'a processor instance'
CarProcessor processor = new CarProcessor()
when: 'processing the car'
processor.process(brand: 'ferrari', model: 'F450', hp: 450)
7 . 26
@NAMEDVARIANT
NamedParam
package madridgug.namedvariant
import java.time.LocalDateTime
import groovy.util.logging.Slf4j
import groovy.transform.*
@Slf4j
class AnotherCarProcessor {
@NamedVariant
void process(String user, @NamedParam LocalDateTime now,
@NamedDelegate Car car) {
log.info "$user ha procesado el modelo ${car.model} el $now"
}
}
7 . 27
@NAMEDVARIANT
Invocacion
and: 'a processor instance'
AnotherCarProcessor processor = new AnotherCarProcessor()
when: 'processing the car'
processor.process(
'John Doe',
now: LocalDateTime.now(),
brand: 'ferrari',
model: 'F450',
hp: 450,
)
7 . 28
@GENERATED
Concebido para los autores de transformciones AST
Ayuda a las herramientas de cobertura de codigo
Para saber que codigo es generado y cual no
Hasta ahora ni JaCoCo ni Cobertura lo tenian facil
7 . 29
MACROS
8 . 1
LAS UTILIDADES DE MACROS
ABSTRAEN…
La generacion de nuevo codigo
El filtrado de codigo sobre el que quieres aplicar una
transformacion
La transformacion de codigo
8 . 2
UTILIDADES
macro {} (generacion)
MacroClass {} (generacion)
@Macro (transformacion)
ASTMatcher (filtrado)
8 . 3
MACRO METHOD
Nos permite crear statements y expressions
De manera mas facil y natural
8 . 4
MACRO METHOD
Este codigo
Deberia contemplar este test
package madridgug.macros.method
class SafeCalls {
@MakeParamSafe
static Integer inc(Integer a) {
// if (!a) { return 1 }
return a + 1
}
}
void 'check unsafe calls'() {
expect: 'unsafe calls to return ok'
SafeCalls.inc(null) == 1
}
8 . 5
MACRO METHOD
Como crear la guarda antes del codigo ?
API AST "A pelo"
GeneralUtils para reducirlo
macro {}
8 . 6
MACRO METHOD
API ASTs
GeneralUtils
IfStatement safeGuard = new IfStatement(
new NotExpression(
new VariableExpression(paramName)
),
new ReturnStatement(new ConstantExpression(1)),
new EmptyStatement()
)
IfStatement safeGuard = ifS(
notX(varX(paramName)),
returnS(constX(1))
) as IfStatement
8 . 7
MACRO METHOD
macro {}
1 Las expressiones se interpolan
2 Dentro de codigo plano
VariableExpression paramRef = Utils.getParamAsVarX(methodNode) (1)
IfStatement safeGuard = macro {
if (! $v { paramRef }) { (2)
return 1
}
}
8 . 8
MACRO METHOD
Mejor caso de uso
BlockStatement getMD5Code(final String propertyName) {
return macro(true) {
java.security.MessageDigest.getInstance('MD5')
.digest(${propertyName}.getBytes('UTF-8'))
.encodeHex()
.toString()
}
}
8 . 9
MACROCLASS
Para crear clases y/o metodos con la misma tecnica que
con el macro {} method
8 . 10
MACROCLASS
Creacion de clase
@CompileDynamic
ClassNode buildTemplateClass(ClassNode reference) {
def methodCount = constX(reference.methods.size())
def fieldCount = constX(reference.fields.size())
return new MacroClass() {
class Statistics {
java.lang.Integer getMethodCount() {
return $v { methodCount }
}
java.lang.Integer getFieldCount() {
return $v { fieldCount }
}
}
}
8 . 11
MACROCLASS
Creacion de clase
package madridgug.macros.method
@Statistics
class ProcessorWithStatistics {
String name
void processX(){}
void processY(){}
void processZ(){}
}
8 . 12
MACROCLASS
Creacion de clase
void 'check statistics'() {
given: 'an instance of processor'
ProcessorWithStatistics processor = new ProcessorWithStatistics()
expect: 'number of methods'
processor.methodCount == 3
and: 'number of fields'
processor.fieldCount == 1
}
8 . 13
ASTMATCHER
Clase de utilidad para filtrar, seleccionar nodos que
transformar
Una vez que localizas lo que quieres modificar lo
modificas
8 . 14
ASTMATCHER
@Override
Expression transform(Expression exp) {
Expression ref = macro { 1 + 1 }
if (ASTMatcher.matches(ref, exp)) {
return macro { 3 }
}
return super.transform(exp)
}
8 . 15
@MACRO
Transforman aquellas invocaciones a metodos que tienen
el nombre anotado
Parecido a las extensiones
No imports required
8 . 16
@MACRO
public class ExampleMacroMethods {
@Macro
public static Expression safe(MacroContext macroContext, MethodCa
return ternaryX(
notNullX(callExpression.getObjectExpression()),
callExpression,
constX(null)
);
}
...
}
8 . 17
@MACRO
def nullObject = null
assert null == safe(safe(nullObject.hashcode()).toString())
8 . 18
@MACRO
nullObject?.hashcode()?.toString()
8 . 19
HABLEMOS DE GROOVY 3.X
9 . 1
ALINEACION CON JDK9 / 10
9 . 2
PARROT
Renovacion del parser de Groovy
Groovy vuelve a ser un super conjunto de Java
Entre otras cosas… lambdas syntax
9 . 3
LAMBDAS
Lambdas
static Integer applyLambdas() {
return Stream
.of(1, 2, 3)
.filter(y -> y % 2 == 0)
.map(y -> y + 1)
.mapToInt(Integer::intValue)
.sum()
}
9 . 4
LAMBDAS
Lambdas
static Integer applyLambdas2() {
return Stream
.of(1, 2, 3)
.reduce((Integer acc, Integer val) -> {
return acc + val
}).orElse(1)
}
9 . 5
METHOD REFERENCES
@CompileStatic
static Integer applyMethodReferences(Integer x) {
return Optional
.ofNullable(x)
.map(Functions::x2)
.map(inc)
.orElse(1)
}
9 . 6
LAMBDAS + CLOSURES + M. REF.
Todo junto
static Integer applyBoth() {
return Stream
.of(1, 2, 3)
.filter { y -> y % 2 == 0 } // closure syntax
.map( y -> y + 1 ) // lambda syntax
.mapToInt(Integer::intValue) // method ref
.sum()
}
9 . 7
LAMBDAS OTHERS
// Sin parentesis
static Function<Integer, Integer> inc = x -> x + 1
// Con valor por defecto (No existe en Java)
static Function<Integer, Integer> dob = (x = 0) -> x * 2
// Con parentesis
static Function<Integer, Integer> tri = (Integer x) -> x * 3
// Con llaves
static Function<Integer, Integer> com = (Integer x) -> {
x + 4
}
9 . 8
LAMBDAS OTHERS
Son las lambdas realmente lambdas ?
Con @CompileStatic ⇒ lambdas
Sin @CompileStatic ⇒ closures
9 . 9
LOOPS
En general todos los tipos de loops que se puedan hacer
en Java
Ahora se puede hacer un do / while por ejemplo
9 . 10
LOOPS
Multi asignacion
List<String> returnValues() {
List<String> values = []
for (def (String u, Integer v) = ['bar', 42]; v < 45; u++, v++) {
values << "$u $v"
}
return values
}
9 . 11
NUEVOS OPERADORES
Identidad
Elvis
Safe indexing
9 . 12
IDENTIDAD
package madridgug.parrot
import groovy.transform.Immutable
class Identity {
@Immutable
class Person {
String name
}
void checkIdentity(Person left, Person right) {
if (left === right) { (1)
log.info "es la misma persona"
}
if (left == right) { (2)
log.info "son personas con caracteristicas iguales"
}
9 . 13
ELVIS
void newElvis(Integer x) {
x ?= 0 // instead of x ? x : 0
println x + 1
}
9 . 14
SAFE INDEXING
void safeIndexing() {
def numbers = null
println numbers?[10] // will print null
}
9 . 15
OTROS
Default methods en interfaces
!in y !instanceof
9 . 16
@GROOVYDOC
Comentarios accesibles en tiempo de ejecucion
9 . 17
@GROOVYDOC
package madridgug.parrot
class Processor {
/**
* @Groovydoc accesible1 (1)
*/
void process(String word) {
println "process: $word"
}
@Groovydoc('accesible2') (2)
void check(String word) {
println "check: $word"
}
}
9 . 18
@GROOVYDOC
comments
annotation
String content = Processor
.methods
.find { it.name == 'process' }
.groovydoc
.content
assert content == 'accesible1 // <1>'
String content = Processor
.methods
.find { it.name == 'check' }
.groovydoc
.content
assert content == 'accesible2'
9 . 19
QUE QUEDA POR CONTAR ?
10 . 1
GROOVY 2.5
@TupleConstructor
Repeated annotations
Anotaciones en mas sitios (JSR-308)
Mejoras en el CliBuilder
with vs tap
10 . 2
GROOVY 3.X
Mejora en la syntaxis try with resources
10 . 3
GROOVY ECOSYSTEM
11 . 1
BIBLIOTECAS Y FRAMEWORKS
Nombre Version Groovy
Spock 1.2-groovy-2.5 2.5.2
Micronaut 1.0.0-RC2 2.5.1
Geb 2.2 2.4.15
Grails 3.3.8 2.4.15
Griffon 2.15.0 2.4.15
11 . 2
WANNA KNOW MORE ?
https://www.youtube.com/watch?v=ECZVbiFZPwE
12
QUESTIONS & ANSWERS
13

Más contenido relacionado

Similar a Groovy 2.5 and 3.0 (Spanish)

Similar a Groovy 2.5 and 3.0 (Spanish) (20)

Empezando con Angular 2
Empezando con Angular 2Empezando con Angular 2
Empezando con Angular 2
 
Groovy&Grails: Cambia la forma de desarrollar tus aplicaciones web
Groovy&Grails: Cambia la forma de desarrollar tus aplicaciones webGroovy&Grails: Cambia la forma de desarrollar tus aplicaciones web
Groovy&Grails: Cambia la forma de desarrollar tus aplicaciones web
 
Cambia la forma de desarrollar tus aplicaciones web con groovy y grails
Cambia la forma de desarrollar tus aplicaciones web con groovy y grailsCambia la forma de desarrollar tus aplicaciones web con groovy y grails
Cambia la forma de desarrollar tus aplicaciones web con groovy y grails
 
GraphQL y Groovy
GraphQL y GroovyGraphQL y Groovy
GraphQL y Groovy
 
Construyendo una app Android sobre la nube App Engine
Construyendo una app Android sobre la nube App EngineConstruyendo una app Android sobre la nube App Engine
Construyendo una app Android sobre la nube App Engine
 
leccion 8
leccion 8leccion 8
leccion 8
 
Jf 3 8_sg_esp(2)(3) 8
Jf 3 8_sg_esp(2)(3) 8Jf 3 8_sg_esp(2)(3) 8
Jf 3 8_sg_esp(2)(3) 8
 
CAPITULO 8 DE GREENFOOT
CAPITULO 8 DE GREENFOOTCAPITULO 8 DE GREENFOOT
CAPITULO 8 DE GREENFOOT
 
Capitulo 8
Capitulo 8Capitulo 8
Capitulo 8
 
Greenfoot 8
Greenfoot 8Greenfoot 8
Greenfoot 8
 
Greenfoot 8
Greenfoot 8Greenfoot 8
Greenfoot 8
 
CAPITULO 8 GREENFOOT
CAPITULO 8 GREENFOOTCAPITULO 8 GREENFOOT
CAPITULO 8 GREENFOOT
 
Capitulo 8
Capitulo 8Capitulo 8
Capitulo 8
 
Greenfoot 8
Greenfoot 8Greenfoot 8
Greenfoot 8
 
Jf 3 8_sg_esp(2)(3)
Jf 3 8_sg_esp(2)(3)Jf 3 8_sg_esp(2)(3)
Jf 3 8_sg_esp(2)(3)
 
Jf 3 8_sg_esp(2)(3)
Jf 3 8_sg_esp(2)(3)Jf 3 8_sg_esp(2)(3)
Jf 3 8_sg_esp(2)(3)
 
Jf 3 8_sg_esp(2)(3)
Jf 3 8_sg_esp(2)(3)Jf 3 8_sg_esp(2)(3)
Jf 3 8_sg_esp(2)(3)
 
Capitulo 8 greenfoot
Capitulo 8  greenfootCapitulo 8  greenfoot
Capitulo 8 greenfoot
 
Greenfoot 8
Greenfoot 8Greenfoot 8
Greenfoot 8
 
Pra8
Pra8Pra8
Pra8
 

Más de Mario García

Blockchain 101 (spanish)
Blockchain 101 (spanish)Blockchain 101 (spanish)
Blockchain 101 (spanish)Mario García
 
Jbake workshop (Greach 2019)
Jbake workshop (Greach 2019)Jbake workshop (Greach 2019)
Jbake workshop (Greach 2019)Mario García
 
Calidad del codigo (MadridGUG)
Calidad del codigo (MadridGUG)Calidad del codigo (MadridGUG)
Calidad del codigo (MadridGUG)Mario García
 
Macro macro, burrito burrit
Macro macro, burrito burritMacro macro, burrito burrit
Macro macro, burrito burritMario García
 
Creating ASTTs The painful truth
Creating ASTTs The painful truthCreating ASTTs The painful truth
Creating ASTTs The painful truthMario García
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with GroovyMario García
 
Test Motherfucker...Test
Test Motherfucker...TestTest Motherfucker...Test
Test Motherfucker...TestMario García
 
Programación concurrente con GPars
Programación concurrente con GParsProgramación concurrente con GPars
Programación concurrente con GParsMario García
 
Greach 2011 : Creando Plugins Con Griffon
Greach 2011 : Creando Plugins Con GriffonGreach 2011 : Creando Plugins Con Griffon
Greach 2011 : Creando Plugins Con GriffonMario García
 

Más de Mario García (15)

Blockchain 101 (spanish)
Blockchain 101 (spanish)Blockchain 101 (spanish)
Blockchain 101 (spanish)
 
Jbake workshop (Greach 2019)
Jbake workshop (Greach 2019)Jbake workshop (Greach 2019)
Jbake workshop (Greach 2019)
 
GraphQL & Ratpack
GraphQL & RatpackGraphQL & Ratpack
GraphQL & Ratpack
 
Calidad del codigo (MadridGUG)
Calidad del codigo (MadridGUG)Calidad del codigo (MadridGUG)
Calidad del codigo (MadridGUG)
 
GraphQL and Groovy
GraphQL and GroovyGraphQL and Groovy
GraphQL and Groovy
 
Macro macro, burrito burrit
Macro macro, burrito burritMacro macro, burrito burrit
Macro macro, burrito burrit
 
Creating ASTTs The painful truth
Creating ASTTs The painful truthCreating ASTTs The painful truth
Creating ASTTs The painful truth
 
Groovy android
Groovy androidGroovy android
Groovy android
 
Groovy on Android
Groovy on AndroidGroovy on Android
Groovy on Android
 
Gpars Workshop 2014
Gpars Workshop 2014Gpars Workshop 2014
Gpars Workshop 2014
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Test Motherfucker...Test
Test Motherfucker...TestTest Motherfucker...Test
Test Motherfucker...Test
 
Programación concurrente con GPars
Programación concurrente con GParsProgramación concurrente con GPars
Programación concurrente con GPars
 
Gradle vs Maven
Gradle vs MavenGradle vs Maven
Gradle vs Maven
 
Greach 2011 : Creando Plugins Con Griffon
Greach 2011 : Creando Plugins Con GriffonGreach 2011 : Creando Plugins Con Griffon
Greach 2011 : Creando Plugins Con Griffon
 

Último

pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITMaricarmen Sánchez Ruiz
 
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxEVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxJorgeParada26
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanamcerpam
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxAlan779941
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estossgonzalezp1
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.FlorenciaCattelani
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21mariacbr99
 
redes informaticas en una oficina administrativa
redes informaticas en una oficina administrativaredes informaticas en una oficina administrativa
redes informaticas en una oficina administrativanicho110
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...JohnRamos830530
 
investigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIinvestigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIhmpuellon
 
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptxEL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptxMiguelAtencio10
 
Buenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxBuenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxFederico Castellari
 

Último (12)

pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNIT
 
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxEVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvana
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estos
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21
 
redes informaticas en una oficina administrativa
redes informaticas en una oficina administrativaredes informaticas en una oficina administrativa
redes informaticas en una oficina administrativa
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
 
investigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIinvestigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXI
 
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptxEL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
 
Buenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxBuenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptx
 

Groovy 2.5 and 3.0 (Spanish)