Upload
infinity
View
996
Download
4
Embed Size (px)
DESCRIPTION
Groovy programing language presentation.For more details see my blog.infinitylx.org.ua
Citation preview
Обзор Groovy
Владислав Мережко
План презентации
●JVM, JRE●Groovy syntax●closures (замыкания)●@notation●aliases●metaprogramming●DSL●GPath●Groovy builder●Integration into enfinity
Все точки над «і»
Groovy — объектно-ориентированный язык программирования разработанный для платформы Java как альтернатива языку Java с возможностями Python, Ruby и Smalltalk.
Groovy завершил процесс стандартизации в Java Community Process JSR 241.
Groovy — объектно-ориентированный язык программирования разработанный для платформы Java как альтернатива языку Java с возможностями Python, Ruby и Smalltalk.
Groovy завершил процесс стандартизации в Java Community Process JSR 241.
Java Virtual Machine
● Вы можете использовать любой код написанный на Java
● Получаете все преимущества языка Java:● стабильность JVM● масштабирование● многопоточность● нулевой порог вхождения для Java программистов● и многое другое
● Вы можете использовать любой код написанный на Java
● Получаете все преимущества языка Java:● стабильность JVM● масштабирование● многопоточность● нулевой порог вхождения для Java программистов● и многое другое
DSL
● Язык полностью поддерживает концепцию Domain Specific Language (DSL)
● С помощью Metaprogramming и динамической природы можно легко реализовать свой собственный язык
● Язык полностью поддерживает концепцию Domain Specific Language (DSL)
● С помощью Metaprogramming и динамической природы можно легко реализовать свой собственный язык
Пример
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
Пример
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
}
Пример
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)
}
Пример
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
}
}
Результат выполнения
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
Замыкание
● Одна из важных особенностей Groovy● Очень много встроенных функций Groovy
принимать замыкания как параметр● Замыкания анонимны● Замыкания имеют доступ к внешним
переменным● Замыкания могуть принимать много переменных
● Одна из важных особенностей Groovy● Очень много встроенных функций Groovy
принимать замыкания как параметр● Замыкания анонимны● Замыкания имеют доступ к внешним
переменным● Замыкания могуть принимать много переменных
Замыкания
● Замыкание имеет вид
{ [аргументиЗамикания->] кодЗамикания }● Все замыкания унаследованы от “Closure”● Чтобы вызвать замыкание можно
воспользоваться один из двух способов
1: closureVar.call();
2: closureVar();
● Замыкание имеет вид
{ [аргументиЗамикания->] кодЗамикания }● Все замыкания унаследованы от “Closure”● Чтобы вызвать замыкание можно
воспользоваться один из двух способов
1: closureVar.call();
2: closureVar();
Пример
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
Пример
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
@ннотации
● Аннотации в Groovy позволяют реализовать множественное наследование (@mixin)
● Делегировать вызови методов к свойству класса (@delegate)
● Расширять любые классы, даже final (@category)
● Создавать сиглтоны (@singleton)● Создавать неизменяемые объекты (@immutable)● Создавать ленивые свойства классов (@lazy)
● Аннотации в Groovy позволяют реализовать множественное наследование (@mixin)
● Делегировать вызови методов к свойству класса (@delegate)
● Расширять любые классы, даже final (@category)
● Создавать сиглтоны (@singleton)● Создавать неизменяемые объекты (@immutable)● Создавать ленивые свойства классов (@lazy)
Пример
@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() {}
}
Пример
@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
Пример
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')
Пример
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")
Пример
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)
Пример
@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()
}
Пример
@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!"
Metaprogramming
● Возможность языка динамически манипулировать другими программами, включая себя
● Динамически добавлять методы
● AST (Abstract Syntax Tree) преобразование
● Возможность языка динамически манипулировать другими программами, включая себя
● Динамически добавлять методы
● AST (Abstract Syntax Tree) преобразование
Metaprogramming
AST бывает двух видов● Глобальное – применяется во время компиляции
ко всем исходным текстам во время компиляции● Локальное — применяются к отдельным
элементам обозначенным специальными аннотациями
AST бывает двух видов● Глобальное – применяется во время компиляции
ко всем исходным текстам во время компиляции● Локальное — применяются к отдельным
элементам обозначенным специальными аннотациями
Пример
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()
Пример
println "Introduction".padRight(15, ".")
println "Introduction".reverse()
//output● Introduction...● noitcudortnI
println "Introduction".padRight(15, ".")
println "Introduction".reverse()
//output● Introduction...● noitcudortnI
Пример
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
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, чем просто «динамическая типизация»
GPath
● GPath аналог XPath, только для любых структур.
● Также есть поддержка Xml
● GPath аналог XPath, только для любых структур.
● Также есть поддержка Xml
Пример
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),
]
Пример
● Можно воспользоваться встроенным функционалом
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"]
Пример
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/)
Groovy builder
● Builder в Groovy позволяет очень легко и быстро создавать сложные иерархические структуры например Xml
● В Groovy уже есть поддержка для Xml (HTML), SWING виджетов, Ant tasks
● Builder в Groovy позволяет очень легко и быстро создавать сложные иерархические структуры например Xml
● В Groovy уже есть поддержка для Xml (HTML), SWING виджетов, Ant tasks
Пример
● Для генерации такой 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>
Пример
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()
}}
Integration into Enfinity