groovy grails types, operators, objects

51
Groovy Types, Operators, Objects, Structures, Closures

Upload: husain-dalal

Post on 08-Aug-2015

91 views

Category:

Software


5 download

TRANSCRIPT

Groovy Types, Operators, Objects,

Structures, Closures

Objects

Optional parentheses

Optional semicolons

Optional return keyword

Optional public keyword for class

Optional private keyword for method variables

Import

Default imports

import java.lang.*import java.util.*import java.io.*import java.net.*import groovy.lang.*import groovy.util.*import java.math.BigIntegerimport java.math.BigDecimal

Static import aliasing

import static Calendar.getInstance as nowassert now().class == Calendar.getInstance().class

Type [email protected] Calculator { int sum(int x, int y) { x+y }}

@TypeChecked(TypeCheckingMode.SKIP)

http://docs.groovy-lang.org/latest/html/documentation/#_typing

Types

String'a single quoted string'

def aMultilineString = '''line oneline twoline three'''

"a double quoted string"

def fooPattern = /.*foo.*/assert fooPattern == '.*foo.*'

GStringsString name = 'Guillaume' // a plain stringGString greeting = "Hello ${name}"assert greeting.toString() == 'Hello Guillaume'

GString sum = "The sum of 2 and 3 equals ${2 + 3}"assert sum.toString() == 'The sum of 2 and 3 equals 5'

Person person = [name: 'Guillaume', age: 36]assert "$person.name is $person.age years old" == 'Guillaume is 36 years old'

GStrings - Lazydef number = 1 def eagerGString = "value == ${number}"def lazyGString = "value == ${ -> number }"

assert eagerGString == "value == 1" assert lazyGString == "value == 1"

number = 2 assert eagerGString == "value == 1" assert lazyGString == "value == 2"

Number// primitive typesbyte b = 1char c = 2short s = 3int i = 4long l = 5

// infinite precisionBigInteger bi = 6

// primitive typesfloat f = 1.234double d = 2.345

// infinite precisionBigDecimal bd = 3.456

Assigning Numberslong creditCardNumber = 1234_5678_9012_3456Llong socialSecurityNumbers = 999_99_9999Ldouble monetaryAmount = 12_345_132.12long maxLong = 0x7fff_ffff_ffff_ffffLlong alsoMaxLong = 9_223_372_036_854_775_807L

assert 42I == new Integer('42')assert 42i == new Integer('42') // lowercase i more readableassert 123L == new Long("123") // uppercase L more readableassert 2147483648 == new Long('2147483648') // Long type used, value too large for an Integerassert 456G == new BigInteger('456')assert 456g == new BigInteger('456')assert 123.45 == new BigDecimal('123.45') // default BigDecimal type usedassert 1.200065D == new Double('1.200065')assert 1.234F == new Float('1.234')assert 1.23E23D == new Double('1.23E23')assert 0b1111L.class == Long // binaryassert 0xFFi.class == Integer // hexadecimalassert 034G.class == BigInteger // octal

Booleanboolean untypedBooleanVar = false

assert (!true) == false assert (!'foo') == false assert (!'') == true assert (![]) == trueassert (![:]) == trueassert (!0) == true

Listsdef arrayList = [1, 2, 3]assert arrayList instanceof java.util.ArrayList

LinkedList otherLinked = [3, 4, 5]

def letters = ['a', 'b', 'c', 'd']letters << 'e' assert letters[ 4] == 'e'assert letters[-1] == 'e' assert letters[1, 3] == ['b', 'd'] assert letters[2..4] == ['C', 'd', 'e']

def multi = [[0, 1], [2, 3]] assert multi[1][0] == 2

ArraysString[] arrStr = ['Ananas', 'Banana', 'Kiwi']

int[] numArr = [1, 2, 3] assert numArr.size() == 3

Integer[][] matrix2 matrix2 = [[1, 2], [3, 4]]assert matrix2 instanceof Integer[][]

Mapsdef colors = [red: '#FF0000', green: '#00FF00', blue: '#0000FF']

assert colors['red'] == colors.red

colors['pink'] = '#FF00FF' colors.yellow = '#FFFF00'

assert colors instanceof java.util.LinkedHashMapassert colors.unknown == null

def numbers = [1: 'one', 2: 'two']

def key = 'name'def person = [key: 'Guillaume'] person = [(key): 'Guillaume']

Enumenum State { up, down}

State st = 'up'assert st == State.up

def val = "up"State st = "${val}"assert st == State.up

Operators

Arithmetic Operatorsassert 3 / 2 == 1.5 //always BigDecimal. Use intDiv()assert 10 % 3 == 1assert 2 ** 3 == 8

TODO: Find how operators work for BigDecimal

Null check

Safe navigation operator (prevent NullPointerException)

def person = Person.find { it.id == 123 } def name = person?.name assert name == null

Ternary operatorresult = (string!=null && string.length()>0) ? 'Found' : 'Not found'result = string ? 'Found' : 'Not found'

Elvis operator

displayName = user.name ? user.name : 'Anonymous' displayName = user.name ?: 'Anonymous'

Direct field access

Direct field access operator

class User { public final String name User(String name) { this.name = name} String getName() { "Name: $name" } }

User user = new User('Bob')assert user.name == 'Name: Bob' assert user.@name == 'Bob'

Method Pointer

Method pointer operator

String str = 'example of method reference' Closure fun = str.&toUpperCase def upper = fun() assert upper == str.toUpperCase()

def doSomething(String str) { str.toUpperCase() } def doSomething(Integer x) { 2*x } def reference = this.&doSomething assert reference('foo') == 'FOO' assert reference(123) == 246

Pattern Matching

Pattern operator

p = ~'foo' p = ~"foo" p = ~$/dollar/slashy $ string/$ p = ~"${pattern}"

Find operator

String text = "some text to match"Matcher m = text =~ /match/ if (!m) { throw new RuntimeException("Oops, text not found!")}

Match operator

Boolean m = text ==~ /match/

Spread operator

Spread operator

class Car { String make String model}ArrayList<Car> cars = [ new Car(make: 'Peugeot', model: '508'), new Car(make: 'Renault', model: 'Clio')] ArrayList<String> makes = cars*.make assert makes == ['Peugeot', 'Renault']

assert makes*.toUpperCase() == ['PEUGEOT', 'RENAULT']

Spread Operator...int function(int x, int y, int z) { x*y+z}def args = [4,5,6] assert function(*args) == 26

def items = [4,5] def list = [1,2,3,*items,6] assert list == [1,2,3,4,5,6]

def m1 = [c:3, d:4] def map = [a:1, b:2, *:m1] assert map == [a:1, b:2, c:3, d:4]

Operator Overloading...

Range operator

def range = 0..5 assert (0..5).collect() == [0, 1, 2, 3, 4, 5] assert (0..<5).collect() == [0, 1, 2, 3, 4] assert (0..5) instanceof List assert (0..5).size() == 6 assert ('a'..'d').collect() == ['a','b','c','d']

CompareTo() operator

assert (1 <=> 1) == 0assert (1 <=> 2) == -1assert (2 <=> 1) == 1assert ('a' <=> 'z') == -1

Operator Overloading...

Contains() operator OR isCase() operator

def list = ['Grace','Rob','Emmy']assert ('Emmy' in list)

Equals() operator

def list1 = ['Groovy 1.8','Groovy 2.0','Groovy 2.3'] def list2 = ['Groovy 1.8','Groovy 2.0','Groovy 2.3'] assert list1 == list2 assert !list1.is(list2)

Coercion operator asType() method

Integer x = 123

String s = x as String

Operator Overloading...

plus() operator

class Bucket { int size Bucket(int size) { this.size = size } Bucket plus(Bucket other) { return new Bucket(this.size + other.size) }}

def b1 = new Bucket(4)def b2 = new Bucket(11)assert (b1 + b2).size == 15

Operator Overloading...

Type Coercion [asType() method]class Polar { double r double phi def asType(Class target) { if (Cartesian==target) { return new Cartesian(x: r*cos(phi), y: r*sin(phi)) } }}class Cartesian { double x double y}

def polar = new Polar(r:1.0,phi:PI/2)Cartesian cartesian = polar

Date and Time operations

https://groovy.codeplex.com/wikipage?title=Dates%20and%20Times

BigDecimal operations

http://groovy.codehaus.org/Groovy+Math

Control Structures

Multiple Assignmentsdef (int i, String j) = [10, 'foo']assert i == 10 && j == 'foo'

def (_, month, year) = "18th June 2009".split()assert "In $month of $year" == 'In June of 2009'

def (a, b, c) = [1, 2]assert a == 1 && b == 2 && c == null

class Coordinates { double latitude double longitude double getAt(int idx) { if (idx == 0) latitude else if (idx == 1) longitude else throw new Exception("Wrong coordinate index, use 0 or 1") }}

Switch Statementdef x = 1.23def result = ""

switch ( x ) { case "foo": result = "found foo" // lets fall through

case "bar": result += "bar"

case [4, 5, 6, 'inList']: result = "list" break

case 12..30: result = "range" break

still switching.. case Integer: result = "integer" break

case Number: result = "number" break

case ~/fo*/: // toString() representation of x matches the pattern? result = "foo regex" break

case { it < 0 }: // or { x < 0 } result = "negative" break

default: result = "default"}

for in loopfor ( i in 0..9 ) {...for ( i in [0, 1, 2, 3, 4] ) {...

def array = (0..4).toArray()for ( i in array ) {

def map = ['abc':1, 'def':2, 'xyz':3]for ( e in map ) { x += e.value}// iterate over values in a mapfor ( v in map.values() ) {...

def text = "abc"for (c in text) {...

Multi Catchtry { /* ... */} catch ( IOException | NullPointerException e ) { /* one block to handle 2 exceptions */}

A closure in Groovy is an open, anonymous, block of code that can take arguments, return a value and be assigned to a variable.

Closures

Defining Closure{ [closureParameters -> ] statements }

Closure closureNoArg = { println 'Done!' } Closure<String> closureWithOneArgAndExplicitType = { String str -> str.toUpperCase() }assert closureWithOneArgAndExplicitType('groovy') == 'GROOVY'

Closure closureWithTwoArgsAndExplicitTypes = { int a, int b -> a+b }assert closureWithTwoArgsAndExplicitTypes.call(1,2) == 3

Closure closureWithTwoArgAndDefaultValue = { int a, int b=2 -> a+b }assert closureWithTwoArgAndDefaultValue(1) == 3

Closure<Boolean> closureWithBooleanReturn = { File it -> it.name.endsWith('.txt') }

Implicit Paramdef greeting = { "Hello, $it!" }assert greeting('Patrick') == 'Hello, Patrick!'

def greeting = { it -> "Hello, $it!" }assert greeting('Patrick') == 'Hello, Patrick!'

Varargs

def concat1 = { String... args -> args.join('') } assert concat1('abc','def') == 'abcdef'

def multiConcat = { int n, String... args -> args.join('')*n}assert multiConcat(2, 'abc','def') == 'abcdefabcdef'

Delegation

Its a Groovy concept to create Domain Specific Language. http://docs.groovy-lang.org/latest/html/documentation/#_delegation_strategy

String methodsstr = "It's a rainy day in Seattle" str -= "rainy "assert str == “It's a day in Seattle”

---------for(str in 'held'..'helm') { print "${str} " }

held hele helf helg helh heli helj helk hell helm

-------str = 'Groovy is groovy, really groovy' result = (str =~ /groovy/).replaceAll('hip')println result

Groovy is hip, really hip

GString closureclass Person { String name String toString() { name }}def sam = new Person(name:'Sam')def lucy = new Person(name:'Lucy')def p = sam// Create a GString with lazy evaluation of "p"def gs = "Name: ${-> p}"assert gs == 'Name: Sam'p = lucyassert gs == 'Name: Lucy'

List methodslst = [1, 3, 4, 1, 8, 9, 2, 6]total = 0lst.each { total += it }println "Total is $total"

doubled = [] //NOT a good examplelst.each { doubled << it * 2 }println doubled

println lst.collect { it * 2 }[2, 6, 8, 2, 16, 18, 4, 12]

lst = [4, 3, 1, 2, 4, 1, 8, 9, 2, 6]println lst.find { it > 4 }

println lst.findAll { it > 4 }[8, 9, 6]

List methods...lst = ['Programming', 'In', 'Groovy']println lst.collect { it.size() }.sum() //19println lst.inject(0) { carryOver, element -> carryOver + element.size() } //19println lst.join(' ') //Programming In Groovy println lst - ['Productive', 'In'] //[Be, Groovy]

println lst.size() //4println lst*.size() //[2, 10, 2, 6]

Map Methodslangs = ['C++' : 'Stroustrup', 'Java' : 'Gosling', 'Lisp' : 'McCarthy']

langs.each { entry -> println "Language $entry.key was authored by $entry.value"}

println langs.collect { language, author -> language.replaceAll("[+]", "P")}

entry = langs.find { language, author -> language.size() > 3}

println "Found $entry.key written by $entry.value"

Map methods...friends = [ briang : 'Brian Goetz', brians : 'Brian Sletten', davidb : 'David Bock', davidg : 'David Geary', scottd : 'Scott Davis', scottl : 'Scott Leberknight', stuarth : 'Stuart Halloway'] groupByFirstName = friends.groupBy { it.value.split(' ')[0] }groupByFirstName.each { firstName, buddies -> println "$firstName : ${buddies.collect { key, fullName -> fullName }.join(', ')}"}

Brian : Brian Goetz, Brian SlettenDavid : David Bock, David GearyScott : Scott Davis, Scott LeberknightStuart : Stuart Halloway

Closure in methoddef transform(List elements, Closure action) { def result = [] elements.each { result << action(it) } result}String describe(Person p) { "$p.name is $p.age"}def action = this.&describe def list = [ new Person(name: 'Bob', age: 42), new Person(name: 'Julia', age: 35)] assert transform(list, action) == ['Bob is 42', 'Julia is 35']

MemoizationMemoization allows the result of the call of a closure to be cached. If the computation done by a function (closure) is slow, but you know that this function is going to be called often with the same arguments.

def fibfib = { long n -> n<2?n:fib(n-1)+fib(n-2) }assert fib(15) == 610 // slow!

fib = { long n -> n<2?n:fib(n-1)+fib(n-2) }.memoize()assert fib(25) == 75025 // fast!

[optional] CurryingCurrying refers to the concept of partial application. It will let you set the value of one parameter of a closure, and it will return a new closure accepting one less argument.

def nCopies = { int n, String str -> str*n } def twice = nCopies.curry(2) assert twice('bla') == 'blabla' assert twice('bla') == nCopies(2, 'bla')

[optional] Composition (Chaining)def plus2 = { it + 2 }def times3 = { it * 3 }

def times3plus2 = plus2 << times3assert times3plus2(3) == 11assert times3plus2(4) == plus2(times3(4))

// reverse compositionassert times3plus2(3) == (times3 >> plus2)(3)