groovy presentation

36
Обзор Groovy Владислав Мережко

Upload: infinity

Post on 25-Jan-2015

999 views

Category:

Technology


4 download

DESCRIPTION

Groovy programing language presentation.For more details see my blog.infinitylx.org.ua

TRANSCRIPT

Page 1: Groovy presentation

Обзор Groovy

Владислав Мережко

Page 2: Groovy presentation

План презентации

●JVM, JRE●Groovy syntax●closures (замыкания)●@notation●aliases●metaprogramming●DSL●GPath●Groovy builder●Integration into enfinity

Page 3: Groovy presentation

Все точки над «і»

Groovy — объектно-ориентированный язык программирования разработанный для платформы Java как альтернатива языку Java с возможностями Python, Ruby и Smalltalk.

Groovy завершил процесс стандартизации в Java Community Process JSR 241.

Groovy — объектно-ориентированный язык программирования разработанный для платформы Java как альтернатива языку Java с возможностями Python, Ruby и Smalltalk.

Groovy завершил процесс стандартизации в Java Community Process JSR 241.

Page 4: Groovy presentation

Java Virtual Machine

● Вы можете использовать любой код написанный на Java

● Получаете все преимущества языка Java:● стабильность JVM● масштабирование● многопоточность● нулевой порог вхождения для Java программистов● и многое другое

● Вы можете использовать любой код написанный на Java

● Получаете все преимущества языка Java:● стабильность JVM● масштабирование● многопоточность● нулевой порог вхождения для Java программистов● и многое другое

Page 5: Groovy presentation

DSL

● Язык полностью поддерживает концепцию Domain Specific Language (DSL)

● С помощью Metaprogramming и динамической природы можно легко реализовать свой собственный язык

● Язык полностью поддерживает концепцию Domain Specific Language (DSL)

● С помощью Metaprogramming и динамической природы можно легко реализовать свой собственный язык

Page 6: Groovy presentation

Пример

buy 500, "AAPL", 179.30

buy(250, "AAPL", 179.30) //

buy 500, "SUNW", 10.14

sell 350, "AAPL", 179.30

show_transactions "AAPL"

print_portfolio_value

buy 500, "AAPL", 179.30

buy(250, "AAPL", 179.30) //

buy 500, "SUNW", 10.14

sell 350, "AAPL", 179.30

show_transactions "AAPL"

print_portfolio_value

Page 7: Groovy presentation

Пример

portfolio = [:] //Holds all of the stock transactions

/**

*A simple object to hold the data for each individual transaction

*/

class StockTransaction {

def tickerSymbol

def numberOfShares

def sharePrice

def type

def transactionDate

}

portfolio = [:] //Holds all of the stock transactions

/**

*A simple object to hold the data for each individual transaction

*/

class StockTransaction {

def tickerSymbol

def numberOfShares

def sharePrice

def type

def transactionDate

}

Page 8: Groovy presentation

Пример

def buy(numberOfShares, symbol, sharePrice){

transaction('Buy', numberOfShares, symbol, sharePrice)

}

def sell(numberOfShares, symbol, sharePrice){

transaction('Sell', numberOfShares, symbol, sharePrice)

}

def buy(numberOfShares, symbol, sharePrice){

transaction('Buy', numberOfShares, symbol, sharePrice)

}

def sell(numberOfShares, symbol, sharePrice){

transaction('Sell', numberOfShares, symbol, sharePrice)

}

Page 9: Groovy presentation

Пример

def transaction(transactionType, numberOfShares, symbol, sharePrice){

def transaction = new StockTransaction(tickerSymbol:symbol,

numberOfShares:numberOfShares, sharePrice:sharePrice,

type:transactionType, transactionDate:new Date())

println "${transaction.type}ing ${transaction.numberOfShares} shares" +

" of ${transaction.tickerSymbol} at ${transaction.sharePrice}"

if(portfolio[transaction.tickerSymbol] == null){

if(transactionType == 'Buy')

portfolio[transaction.tickerSymbol] = [transaction]

else

println "You can't sell a stock you don't own."

} else{

portfolio[transaction.tickerSymbol] << transaction

}

}

def transaction(transactionType, numberOfShares, symbol, sharePrice){

def transaction = new StockTransaction(tickerSymbol:symbol,

numberOfShares:numberOfShares, sharePrice:sharePrice,

type:transactionType, transactionDate:new Date())

println "${transaction.type}ing ${transaction.numberOfShares} shares" +

" of ${transaction.tickerSymbol} at ${transaction.sharePrice}"

if(portfolio[transaction.tickerSymbol] == null){

if(transactionType == 'Buy')

portfolio[transaction.tickerSymbol] = [transaction]

else

println "You can't sell a stock you don't own."

} else{

portfolio[transaction.tickerSymbol] << transaction

}

}

Page 10: Groovy presentation

Результат выполнения

Buying 500 shares of AAPL at 179.30

Buying 250 shares of AAPL at 179.30

Buying 500 shares of SUNW at 10.14

Selling 350 shares of AAPL at 179.30

Sun Aug 17 19:15:05 EDT 2008: Buy 500 shares of AAPL at 179.30

Sun Aug 17 19:15:05 EDT 2008: Buy 250 shares of AAPL at 179.30

Sun Aug 17 19:15:05 EDT 2008: Sell 350 shares of AAPL at 179.30

Your Total Portfolio Value is: 76790.00

Buying 500 shares of AAPL at 179.30

Buying 250 shares of AAPL at 179.30

Buying 500 shares of SUNW at 10.14

Selling 350 shares of AAPL at 179.30

Sun Aug 17 19:15:05 EDT 2008: Buy 500 shares of AAPL at 179.30

Sun Aug 17 19:15:05 EDT 2008: Buy 250 shares of AAPL at 179.30

Sun Aug 17 19:15:05 EDT 2008: Sell 350 shares of AAPL at 179.30

Your Total Portfolio Value is: 76790.00

Page 11: Groovy presentation

Замыкание

● Одна из важных особенностей Groovy● Очень много встроенных функций Groovy

принимать замыкания как параметр● Замыкания анонимны● Замыкания имеют доступ к внешним

переменным● Замыкания могуть принимать много переменных

● Одна из важных особенностей Groovy● Очень много встроенных функций Groovy

принимать замыкания как параметр● Замыкания анонимны● Замыкания имеют доступ к внешним

переменным● Замыкания могуть принимать много переменных

Page 12: Groovy presentation

Замыкания

● Замыкание имеет вид

{ [аргументиЗамикания->] кодЗамикания }● Все замыкания унаследованы от “Closure”● Чтобы вызвать замыкание можно

воспользоваться один из двух способов

1: closureVar.call();

2: closureVar();

● Замыкание имеет вид

{ [аргументиЗамикания->] кодЗамикания }● Все замыкания унаследованы от “Closure”● Чтобы вызвать замыкание можно

воспользоваться один из двух способов

1: closureVar.call();

2: closureVar();

Page 13: Groovy presentation

Пример

square = { it * it }

square(9)● 81

[ 1, 2, 3, 4 ].collect(square)● [1, 4, 9, 16 ]

def printSum = { a, b -> print a+b }

printSum( 5, 7 )● 12

square = { it * it }

square(9)● 81

[ 1, 2, 3, 4 ].collect(square)● [1, 4, 9, 16 ]

def printSum = { a, b -> print a+b }

printSum( 5, 7 )● 12

Page 14: Groovy presentation

Пример

def myConst = 5

def incByConst = { num-> num + myConst}

println incByConst(10)● 15

def clos = { print it }

clos( "hi there" ) ● hi there

def myConst = 5

def incByConst = { num-> num + myConst}

println incByConst(10)● 15

def clos = { print it }

clos( "hi there" ) ● hi there

Page 15: Groovy presentation

@ннотации

● Аннотации в Groovy позволяют реализовать множественное наследование (@mixin)

● Делегировать вызови методов к свойству класса (@delegate)

● Расширять любые классы, даже final (@category)

● Создавать сиглтоны (@singleton)● Создавать неизменяемые объекты (@immutable)● Создавать ленивые свойства классов (@lazy)

● Аннотации в Groovy позволяют реализовать множественное наследование (@mixin)

● Делегировать вызови методов к свойству класса (@delegate)

● Расширять любые классы, даже final (@category)

● Создавать сиглтоны (@singleton)● Создавать неизменяемые объекты (@immutable)● Создавать ленивые свойства классов (@lazy)

Page 16: Groovy presentation

Пример

@Singleton class T {}

● Аналог на Java

public class T {

public static final T instance = new T();

private T() {}

}

@Singleton class T {}

● Аналог на Java

public class T {

public static final T instance = new T();

private T() {}

}

Page 17: Groovy presentation

Пример

@Immutable final class Coordinates {

Double latitude, longitude

}

def c1 = new Coordinates(latitude: 48.824068, longitude: 2.531733)

def c2 = new Coordinates(48.824068, 2.531733)

● assert c1 == c2

@Immutable final class Coordinates {

Double latitude, longitude

}

def c1 = new Coordinates(latitude: 48.824068, longitude: 2.531733)

def c2 = new Coordinates(48.824068, 2.531733)

● assert c1 == c2

Page 18: Groovy presentation

Пример

class Person {

@Lazy pets = ['Cat', 'Dog', 'Bird']

}

def p = new Person()

assert !(p.dump().contains('Cat'))

assert p.pets.size() == 3

assert p.dump().contains('Cat')

class Person {

@Lazy pets = ['Cat', 'Dog', 'Bird']

}

def p = new Person()

assert !(p.dump().contains('Cat'))

assert p.pets.size() == 3

assert p.dump().contains('Cat')

Page 19: Groovy presentation

Пример

import java.text.SimpleDateFormat

class Event {

@Delegate Date when

String title, url

}

def df = new SimpleDateFormat("yyyy/MM/dd")

import java.text.SimpleDateFormat

class Event {

@Delegate Date when

String title, url

}

def df = new SimpleDateFormat("yyyy/MM/dd")

Page 20: Groovy presentation

Пример

def gr8conf = new Event(title: "GR8 Conference",

url: "http://www.gr8conf.org",

when: df.parse("2009/05/18"))

def javaOne = new Event(title: "JavaOne",

url: "http://java.sun.com/javaone/",

when: df.parse("2009/06/02"))

assert gr8conf.before(javaOne.when)

def gr8conf = new Event(title: "GR8 Conference",

url: "http://www.gr8conf.org",

when: df.parse("2009/05/18"))

def javaOne = new Event(title: "JavaOne",

url: "http://java.sun.com/javaone/",

when: df.parse("2009/06/02"))

assert gr8conf.before(javaOne.when)

Page 21: Groovy presentation

Пример

@Category(Vehicle) class FlyingAbility {

def fly() { "I'm the ${name} and I fly!" }

}

@Category(Vehicle) class DivingAbility {

def dive() { "I'm the ${name} and I dive!" }

}

interface Vehicle {

String getName()

}

@Category(Vehicle) class FlyingAbility {

def fly() { "I'm the ${name} and I fly!" }

}

@Category(Vehicle) class DivingAbility {

def dive() { "I'm the ${name} and I dive!" }

}

interface Vehicle {

String getName()

}

Page 22: Groovy presentation

Пример

@Mixin([DivingAbility, FlyingAbility])

class JamesBondVehicle implements Vehicle {

String getName() { "James Bond's vehicle" }

}

assert new JamesBondVehicle().fly() ==

"I'm the James Bond's vehicle and I fly!"

assert new JamesBondVehicle().dive() ==

"I'm the James Bond's vehicle and I dive!"

@Mixin([DivingAbility, FlyingAbility])

class JamesBondVehicle implements Vehicle {

String getName() { "James Bond's vehicle" }

}

assert new JamesBondVehicle().fly() ==

"I'm the James Bond's vehicle and I fly!"

assert new JamesBondVehicle().dive() ==

"I'm the James Bond's vehicle and I dive!"

Page 23: Groovy presentation

Metaprogramming

● Возможность языка динамически манипулировать другими программами, включая себя

● Динамически добавлять методы

● AST (Abstract Syntax Tree) преобразование

● Возможность языка динамически манипулировать другими программами, включая себя

● Динамически добавлять методы

● AST (Abstract Syntax Tree) преобразование

Page 24: Groovy presentation

Metaprogramming

AST бывает двух видов● Глобальное – применяется во время компиляции

ко всем исходным текстам во время компиляции● Локальное — применяются к отдельным

элементам обозначенным специальными аннотациями

AST бывает двух видов● Глобальное – применяется во время компиляции

ко всем исходным текстам во время компиляции● Локальное — применяются к отдельным

элементам обозначенным специальными аннотациями

Page 25: Groovy presentation

Пример

import java.text.NumberFormat

BigDecimal.metaClass.inEuros = {

def EXCHANGE_RATE = 0.53 // (6/16/2011)

NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US)

nf.setCurrency(Currency.getInstance("EUR"))

nf.format(delegate * EXCHANGE_RATE)

}

● println 2500.00.inEuros()

import java.text.NumberFormat

BigDecimal.metaClass.inEuros = {

def EXCHANGE_RATE = 0.53 // (6/16/2011)

NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US)

nf.setCurrency(Currency.getInstance("EUR"))

nf.format(delegate * EXCHANGE_RATE)

}

● println 2500.00.inEuros()

Page 26: Groovy presentation

Пример

println "Introduction".padRight(15, ".")

println "Introduction".reverse()

//output● Introduction...● noitcudortnI

println "Introduction".padRight(15, ".")

println "Introduction".reverse()

//output● Introduction...● noitcudortnI

Page 27: Groovy presentation

Пример

String.metaClass.shout = {->

return delegate.toUpperCase()

}

String.metaClass.toUpperCase = {->

return delegate.toLowerCase()

}

println "Hello MetaProgramming".shout()

//output

hello metaprogramming

String.metaClass.shout = {->

return delegate.toUpperCase()

}

String.metaClass.toUpperCase = {->

return delegate.toLowerCase()

}

println "Hello MetaProgramming".shout()

//output

hello metaprogramming

Page 28: Groovy presentation

Aliases and Duck typing

Тут все просто

● def p = System.out.&println;

● p{"Hello"}

● Duck - typing – возможность утверждать что объект имеет определенный тип не на основе наличия в сигнатуре интерфейса, который он имплементирует, а по наличию реализованных методов (оператор AS).

● По сути и это есть более правильный термин для описания типизации в Groovy, чем просто «динамическая типизация»

Тут все просто

● def p = System.out.&println;

● p{"Hello"}

● Duck - typing – возможность утверждать что объект имеет определенный тип не на основе наличия в сигнатуре интерфейса, который он имплементирует, а по наличию реализованных методов (оператор AS).

● По сути и это есть более правильный термин для описания типизации в Groovy, чем просто «динамическая типизация»

Page 29: Groovy presentation

GPath

● GPath аналог XPath, только для любых структур.

● Также есть поддержка Xml

● GPath аналог XPath, только для любых структур.

● Также есть поддержка Xml

Page 30: Groovy presentation

Пример

class Person{

String firstName

String lastName

int age

}

def personList = [

new Person(firstName: "dhaval", lastName: "nagar", age: 25),

new Person(firstName: "nachiket", lastName: "patel", age: 24),

]

class Person{

String firstName

String lastName

int age

}

def personList = [

new Person(firstName: "dhaval", lastName: "nagar", age: 25),

new Person(firstName: "nachiket", lastName: "patel", age: 24),

]

Page 31: Groovy presentation

Пример

● Можно воспользоваться встроенным функционалом

println personList.collect{it.firstName}

// will print ["dhaval", "nachiket"]

● А можно GPath

println personList.firstName

println personList.firstName.grep(~/d.*/)

// will print ["dhaval"]

● Можно воспользоваться встроенным функционалом

println personList.collect{it.firstName}

// will print ["dhaval", "nachiket"]

● А можно GPath

println personList.firstName

println personList.firstName.grep(~/d.*/)

// will print ["dhaval"]

Page 32: Groovy presentation

Пример

def mylinks = """

<links>

<link id="1" url="www.google.com"/>

<link id="2" url="www.apple.co.in"/>

</links>

"""

● Для нахождения ссылок с окончанием "com" и "co.in":

println [email protected](~/.*com/)

println [email protected](~/.*co[.]in/)

def mylinks = """

<links>

<link id="1" url="www.google.com"/>

<link id="2" url="www.apple.co.in"/>

</links>

"""

● Для нахождения ссылок с окончанием "com" и "co.in":

println [email protected](~/.*com/)

println [email protected](~/.*co[.]in/)

Page 33: Groovy presentation

Groovy builder

● Builder в Groovy позволяет очень легко и быстро создавать сложные иерархические структуры например Xml

● В Groovy уже есть поддержка для Xml (HTML), SWING виджетов, Ant tasks

● Builder в Groovy позволяет очень легко и быстро создавать сложные иерархические структуры например Xml

● В Groovy уже есть поддержка для Xml (HTML), SWING виджетов, Ant tasks

Page 34: Groovy presentation

Пример

● Для генерации такой Xml структуры

<person>

<name first="Megan" last="Smith">

<age>32</age>

<gender>female</gender>

</name>

<friends>

<friend>Julie</friend>

<friend>Joe</friend>

<friend>Hannah</friend>

</friends>

</person>

● Для генерации такой Xml структуры

<person>

<name first="Megan" last="Smith">

<age>32</age>

<gender>female</gender>

</name>

<friends>

<friend>Julie</friend>

<friend>Joe</friend>

<friend>Hannah</friend>

</friends>

</person>

Page 35: Groovy presentation

Пример

class XMLBuilder{

static void main(String[] args) {

def writer = new StringWriter()

def builder = new groovy.xml.MarkupBuilder(writer)

def friendnames = [ "Julie", "Joey", "Hannah"]

builder.person() {

name(first:"Megan", last:"Smith") {

age("32")

gender("female")

}

friends() {

for (e in friendnames) { friend(e) }

}}

println writer.toString()

}}

class XMLBuilder{

static void main(String[] args) {

def writer = new StringWriter()

def builder = new groovy.xml.MarkupBuilder(writer)

def friendnames = [ "Julie", "Joey", "Hannah"]

builder.person() {

name(first:"Megan", last:"Smith") {

age("32")

gender("female")

}

friends() {

for (e in friendnames) { friend(e) }

}}

println writer.toString()

}}

Page 36: Groovy presentation

Integration into Enfinity