Breaking Down the Flutterwave Scandal What You Need to Know.pdf
Groovy Online 100
1. Subscribe Now for FREE! refcardz.com
tech facts at your fingertips
CONTENTS INCLUDE:
Groovy
n
Groovy/Java Integration
n
Language Elements
n
Operators
n
Collective Datatypes
Meta Programming
By Dierk König
n
n
Hot Tips and more...
GroovyShell
ABOUT gROOVY Use groovy.util.GroovyShell for more flexibility in the Binding
and optional pre-parsing:
Groovy is a dynamic language for the Java™ Virtual Machine
(JVM). It shines with full object-orientation, scriptability, optional GroovyShell shell= new GroovyShell();
typing, operator customization, lexical declarations for the Script scpt = shell.parse(quot;y = x*xquot;);
most common data types, advanced concepts like closures and Binding binding = new Binding();
ranges, compact property syntax and seamless Java™ integra- scpt.setBinding(binding);
tion. This reference card provides exactly the kind of information binding.setVariable(quot;xquot;, 2);
you are likely to look up when programming Groovy.
scpt.run();
(int) binding.getVariable(quot;yquot;);
STARTINg gROOVY
Chapter 11 of Groovy in Action has more details about
Install Groovy from http://groovy.codehaus.org and you will integration options. Here is an overview:
have the following commands available:
Integration option Features/properties
Command Purpose Eval/GroovyShell for small expressions + reloading, security
www.dzone.com
groovy Execute Groovy code GroovyScriptEngine for dependent scripts + reloading
groovyc Compile Groovy code - classes, security
groovysh Open Groovy shell GroovyClassLoader the catch-all solution + reloading, security
groovyConsole Open Groovy UI console Spring Beans integrates with Spring + reloading
java2groovy Migration helper JSR-223 easy language switch but limited in API
- reloading, security
requires Java 6
The groovy command comes with -h and --help options to
show all options and required arguments. Typical usages are:
Execute file MyScript.groovy LANgUAgE ELEmENTS
groovy MyScript
Evaluate (e) on the command line Classes & Scripts
groovy -e quot;print 12.5*Math.PIquot; A Groovy class declaration looks like in Java. Default visibility
modifier is public
Print (p) for each line of input
echo 12.5 | groovy -pe class MyClass {
quot;line.toDouble() * Math.PIquot; void myMethod(String argument) {
Inline edit (i) file data.txt by reversing each line and save a backup }
groovy -i.bak –pe } →
quot;line.reverse()quot; data.txt
gROOVY / JAVA INTEgRATION Get More Refcardz
(They’re free!)
From Groovy, you can call any Java code like you would do from
Java. It’s identical.
n Authoritative content
n Designed for developers
From Java, you can call Groovy code in the following ways.
Note that you need to have the groovy-all.jar in your classpath.
n Written by top experts
n Latest tools & technologies
Cross-compilation n Hot tips & examples
Use groovyc, the <groovyc/> ant task or your IDE integration to
compile your groovy code together with your Java code. This
n Bonus content online
Groovy
enables you to use your Groovy code as if it was written in Java.
n New issue every 1-2 weeks
Eval Subscribe Now for FREE!
Use class groovy.util.Eval for evaluating simple code that is
Refcardz.com
captured in a Java String: (int) Eval.xyz(1,2,3,quot;x+y+zquot;);
DZone, Inc. | www.dzone.com
2. 2
Groovy
tech facts at your fingertips
Language Elements (Classes and Scripts), continued Customizable Operators, continued
When a .groovy file or any other source of Groovy code Operator Method
contains code that is not enclosed in a class declaration, a-- a.previous()
--a
then this code is considered a Script, e.g.
a**b a.power(b)
println quot;Hello Worldquot; a|b a.or(b)
a&b a.and(b)
Scripts differ from classes in that they have a Binding that
a^b a.xor(b)
serves as a container for undeclared references (that are not
~a ~a a.bitwiseNegate() // sometimes referred to as negate
allowed in classes). | +a a.positive() // sometimes referred to as unaryMinus
| -a a.negative() // sometimes referred to as unaryPlus
println text // expected in Binding
a[b] a.getAt(b)
result = 1 // is put into Binding
a[b] = c a.putAt(b, c)
Optional Typing a << b a.leftShift(b)
Static types can be used like in Java and will be obeyed a >> b a.rightShift(b)
at runtime. Dynamic typing is used by replacing the type a >>> b a.rightShiftUnsigned(b)
declaration with the def keyword. Formal parameters to switch(a){ b.isCase(a)
case b: // b is a classifier
method and closure declarations can even omit the def. }
[a].grep(b)
Properties if(a in b)
Properties are declared as fields with the default visibility a == b a.equals(b)
modifier, no matter what type is used. a != b ! a.equals(b)
a <=> b a.compareTo(b)
class MyClass {
a>b a.compareTo(b) > 0
String stringProp
a >= b a.compareTo(b) >= 0
def dynamicProp
} a<b a.compareTo(b) < 0
a <= b a.compareTo(b) <= 0
Java-style getters and setters are compiled into the bytecode
a as B a.asType(B)
automatically.
Properties are referred to like
Actively look for opportunities to implement
println obj.stringProp // getter Hot operator methods in your own Groovy class.
obj.dynamicProp = 1 // setter Tip This often leads to more expressive code.
regardless of whether obj was written in Java or Groovy, the Typical candidates are ==, <=>, +, -, <<,
respective getters/setters will be called. and isCase(). See also Ranges.
Multimethods
Methods are dispatched by the runtime type, allowing code like Special Operators
class Pers { Operator Meaning Name
String name a?b:c if (a) b else c ternary if
boolean equals(Pers other) {
a ?: b a?a:b Elvis
name == other.name
a?.b a==null ? a : a.b null safe
}
a(*list) a(list[0], list[1], ...) spread
}
list*.a() [list[0].a(), list[1].a() ...] spread-dot
assert new Pers(name:'x') == new Pers(name:'x')
a.&b reference to method b in method closure
assert new Pers(name:'x') != 1
object a as closure
a.@field direct field access dot-at
OPERATORS
SImPLE DATATYPES
Customizable Operators
Operators can be customized by implementing/ overriding Numbers
the respective method. All Groovy numbers are objects, not primitive types. Literal
Operator Method
declarations are:
a+b a.plus(b) Type Example literals
a–b a.minus(b) java.lang.Integer 15, 0x1234ffff
a*b a.multiply(b) java.lang.Long 100L, 100l
java.lang.Float 1.23f, 4.56F
a/b a.div(b)
java.lang.Double 1.23d, 4.56D
a%b a.mod(b)
java.math.BigInteger 123g, 456G
a++ a.next()
++a java.math.BigDecimal 1.23, 4.56, 1.4E4, 2.8e4, 1.23g, 1.23G
DZone, Inc. | www.dzone.com
3. 3
Groovy
tech facts at your fingertips
Simple Datatypes (Numbers), continued Regular Expressions, continued
Coercion rules for math operations are explained in Groovy Symbol Meaning
in Action, chapter 3. Some examples to remember are: . any character
^ start of line (or start of document, when in single-line mode)
Expression Result type $ end of line (or end of document, when in single-line mode)
1f * 2f Double d digit character
1f / 2f Double D any character except digits
(Byte)1 + (Byte)2 Integer s whitespace character
1 * 2L Long S any character except whitespace
1/2 BigDecimal (0.5) w word character
(int)(1/2) Integer (0) W any character except word characters
1.intdiv(2) Integer (0) b word boundary
Integer.MAX_VALUE+1 Integer () grouping
2**31 Integer (x|y) x or y as in (Groovy|Java|Ruby)
2**33 Long 1 backmatch to group one, e.g. find doubled characters with (.)1
2**3.5 Double x* zero or more occurrences of x.
2G + 1G BigInteger x+ one or more occurrences of x.
2.5G + 1G BigDecimal x? zero or one occurrence of x.
1.5G == 1.5F Boolean (true) x{m,n} at least “m” and at most “n” occurrences of x.
1.1G == 1.1F Boolean (false) x{m} exactly “m” occurrences of x.
[a-f] character class containing the characters 'a', 'b', 'c', 'd', 'e', 'f'
Strings [^a] character class containing any character except 'a'
'literal String' (?is:x) switches mode when evaluating x; i turns on ignoreCase, s single-line mode
'''literal (?=regex) positive lookahead
multiline String''' (?<=text) positive lookbehind
def lang = 'Groovy'
quot;GString for $langquot;
quot;$lang has ${lang.size()} charsquot;
COLLECTIVE DATATYPES
quot;quot;quot;multiline GString with
Ranges
late eval at ${-> new Date()}quot;quot;quot;
Ranges appear inclusively like 0..10 or half-exclusively like
Placeholders in GStrings are dereferenced at declaration time 0..<10. They are often enclosed in parentheses since the
but their text representation is queried at GString String range operator has low precedence.
conversion time. assert (0..10).contains(5)
/String with unescaped included/ assert (0.0..10.0).containsWithinBounds(3.5)
for (item in 0..10) { println item }
Regular Expressions
for (item in 10..0) { println item }
The regex find operator =~ (0..<10).each { println it }
The regex match operator ==~
Integer ranges are often used for selecting sublists. Range
The regex Pattern operator ~String
boundaries can be of any type that defines previous(), next() and
Examples: implements Comparable. Notable examples are String and Date.
def twister = 'she sells sea shells'
// contains word 'she' Lists
assert twister =~ 'she' Lists look like arrays but are of type java.util.List plus new methods.
// starts with 'she' and ends with 'shells' [1,2,3,4] == (1..4)
assert twister ==~ /she.*shells/ [1,2,3] + [1] == [1,2,3,1]
// same precompiled [1,2,3] << 1 == [1,2,3,1]
def pattern = ~/she.*shells/ [1,2,3,1] - [1] == [2,3]
assert pattern.matcher(twister).matches() [1,2,3] * 2 == [1,2,3,1,2,3]
[1,[2,3]].flatten() == [1,2,3]
// matches are iterable [1,2,3].reverse() == [3,2,1]
// words that start with 'sh' [1,2,3].disjoint([4,5,6]) == true
def shwords = (twister =~ /bshw*/).collect{it}.join(' ') [1,2,3].intersect([4,3,1]) == [3,1]
assert shwords == 'she shells' [1,2,3].collect{ it+3 } == [4,5,6]
[1,2,3,1].unique().size() == 3
// replace through logic [1,2,3,1].count(1) == 2
assert twister.replaceAll(/w+/){ [1,2,3,4].min() == 1
it.size() [1,2,3,4].max() == 4
} == '3 5 3 6' [1,2,3,4].sum() == 10
[4,2,1,3].sort() == [1,2,3,4]
// regex groups to closure params
[4,2,1,3].findAll{it%2 == 0} == [4,2]
// find words with same start and end
def anims=['cat','kangaroo','koala']
def matcher = (twister =~ /(w)(w+)1/) anims[2] == 'koala'
matcher.each { full, first, rest -> def kanims = anims[1..2]
assert full in ['sells','shells'] anims.findAll{it =~ /k.*/} ==kanims
assert first == 's' anims.find{ it =~ /k.*/} ==kanims[0]
} anims.grep(~/k.*/) ==kanims
→
DZone, Inc. | www.dzone.com
4. 4
Groovy
tech facts at your fingertips
Collective Datatypes, continued
CLOSURES
Lists
The sort() method is often used and comes in three flavors: Closures capture a piece of logic and the enclosing scope.
They are first-class objects and can receive messages, can
Sort call Usage
col.sort() natural sort for comparable objects be returned from method calls, stored in fields, and used as
col.sort { applying the closure to each item before comparing arguments to a method call.
it.propname the results
} Use in method parameter
col.sort { a,b -> closure defines a comparator for each comparison
a <=> b def forEach(int i, Closure yield){
} for (x in 1..i) yield(x)
Lists can also be indexed with negative indexes and }
reversed ranges. Use as last method argument
def list = [0,1,2] forEach(3) { num -> println num }
assert list[-1] == 2
assert list[-1..0] == list.reverse() Construct and assign to local variable
assert list == [list.head()] + list.tail() def squareIt = { println it * it}
Sublist assignments can make a list grow or shrink and lists forEach(3, squareIt)
can contain varying data types. Bind leftmost closure param to fixed argument
list[1..2] = ['x','y','z'] def multIt = {x, y -> println x * y}
assert list == [0,'x','y','z'] forEach 3, multIt.curry(2)
forEach 3, multIt.curry('-')
Maps
Maps are like lists that have an arbitrary type of key instead Closure parameter list examples:
of integer. Therefore, the syntax is very much aligned.
Closure Parameters
def map = [a:0, b:1]
{ ... } zero or one (implicit 'it')
Maps can be accessed in a conventional square-bracket
{-> ... } zero
syntax or as if the key was a property of the map.
{x -> ... } one
assert map['a'] == 0
assert map.b == 1 {x=1 -> ... } one or zero with default
map['a'] = 'x' {x,y -> ... } two
map.b = 'y'
{ String x -> ... } one with static type
assert map == [a:'x', b:'y']
There is also an explicit get method that optionally takes a Closure.isCase(b) sends b to the closure and returns the call
default value. result as boolean. Use as in
assert map.c == null
switch ('xy'){
assert map.get('c',2) == 2
assert map.c == 2 case {it.startsWith('x')} :...
}
Map iteration methods take the nature of Map.Entry objects
[0,1,2].grep { it%2 == 0 }
into account.
map.each { entry ->
println entry.key gDK
println entry.value
}
map.each { key, value -> Methods for java.lang.Object
println quot;$key $valuequot;
Get object info
}
for (entry in map) { println obj.dump()
println quot;$entry.key $entry.valuequot;
} or in a GUI
import groovy.inspect.swingui.*
GPath
ObjectBrowser.inspect(obj)
Calling a property on a list returns a list of the property for
each item in the list. Print properties, methods, and fields of obj
employees.address.town println obj.properties
returns a list of town objects. println obj.class.methods.name
println obj.class.fields.name
To do the same with method calls, use the spread-dot operator.
employees*.bonus(2008) Two ways to invoke a method dynamically
calls the bonus method on each employee and stores the obj.invokeMethod(name, paramsAry)
result in a list. obj.quot;$namequot;(params)
DZone, Inc. | www.dzone.com
5. 5
Groovy
tech facts at your fingertips
Files and I/0, continued
gDK
Often used reading methods
GDK (Methods for java.lang.Object). continued def file = new File('/data.txt')
Further methods println file.text
is(other) // identity check (also for Reader, URL, InputStream,Process)
isCase(candidate) //default:equality
def listOfLines = file.readLines()
obj.identity {...}; obj.with {...}
file.eachLine { line -> ... }
print(); print(value),
println(); println(value) file.splitEachLine(/s/) { list -> }
printf(formatStr, value) file.withReader { reader -> ... }
printf(formatStr, value[]) (also for Reader, URL, InputStream)
sleep(millis)
sleep(millis) { onInterrupt } file.withInputStream { is -> ...}
use(categoryClass) { ... } (also for URL)
use(categoryClassList) { ... }
Often-used writing methods
Every object is iterable in Groovy— even if it was implemented
out << 'content'
in Java. See Groovy in Action, chapter 9 on what strategy
for out of type File, Writer, OutputStream, Socket, and Process
Groovy applies to make this happen.
file.withWriter('ASCII') {writer -> }
Not only can you use any obj in loops like
file.withWriterAppend('ISO8859-1'){
for (element in obj) { ... }
writer -> ... }
but you can also apply the following iterative objects methods:
Reading and writing with Strings
Returns Purpose
def out = new StringWriter()
Boolean any {...} out << 'something'
List collect {...} def str = out.toString()
Collection collect(Collection collection) {...} def rdr = new StringReader(str)
(void) each {...} println rdr.readLines()
(void) eachWithIndex {item, index-> ...} Connecting readers and writers
Boolean every {...}
writer << reader
Object find {...}
Special logic for writable objects, e.g. writeTo()
List findAll {...}
writer << obj
Integer findIndexOf {...}
Integer findIndexOf(startIndex) {...} Transform (with closure returning the replacement) and filter
Integer findLastIndexOf {...} (with closure returning boolean)
Integer findLastIndexOf(startIndex) {...} reader.transformChar(writer){c -> }
List findIndexValues {...} reader.transformLine(writer){line-> }
List findIndexValues(startIndex) {...} src.filterLine(writer){line-> }
writer << src.filterLine {line -> }
Object inject(startValue) {temp, item -> ...}
List grep(Object classifier) For src in File, Reader, InputStream
// uses classifier.isCase(item)
Threads & Processes
Two ways of spawning new threads
Implement the iterator() method that returns
Hot an Iterator object to give your own Groovy def thread = Thread.start { ... }
Tip class meaningful iterable behavior with the def t = Thread.startDaemon { ... }
above methods. Two ways of talking to an external process
('cmd /c' is for Windows platforms only)
Files and I/0 today = 'cmd /c date /t'
Often-used filesystem methods .execute().text.split(/D/)
def dir = new File('somedir') proc = ['cmd','/c','date']
def cl = {File f -> println f} .execute()
dir.eachDir cl Thread.start {System.out << proc.in}
dir.eachFile cl Thread.start {System.err << proc.err}
dir.eachDirRecurse cl proc << 'no-such-date' + quot;nquot;
dir.eachFileRecurse cl proc << today.join('-') + quot;nquot;
dir.eachDirMatch(~/.*/, cl) proc.out.close()
dir.eachFileMatch(~/.*/, cl) proc.waitForOrKill(0)
DZone, Inc. | www.dzone.com
6. 6
Groovy
tech facts at your fingertips
XmL
SQL, continued
Alternative with using a datasource
import org.hsqldb.jdbc.*
Reading XML def source = new jdbcDataSource()
Decide to use the parser (for state-based processing) or the source.database = 'jdbc:hsqldb:mem:GInA'
slurper (for flow-based processing) source.user = 'user-name'
def parser = new XmlParser() source.password = 'password'
def slurper = new XmlSlurper() def db = new groovy.sql.Sql(source)
Common parse methods: Submitting Queries
parse(org.xml.saxInputSource)
When a query contains wildcards, it is wise to use a
parse(File)
PreparedStatement. Groovy SQL does this automatically when
parse(InputStream) you supply either the list of values in an extra list or when the
parse(Reader) statement is a GString. So each method below has three variants:
parse(String uri) method('SELECT ... ')
parseText(String text) method('SELECT ...?,?', [x,y])
method(quot;SELECT ... $x,$yquot;)
The parse methods of parser and slurper return different ob-
jects (Node vs. GPathResult) but you can apply the following Returns Method name Parameters
methods on both: boolean execute prepStmt
Integer executeUpdate prepStmt
result.name()
void eachRow prepStmt
result.text() { row -> }
result.toString() void query prepStmt
result.parent() { resultSet -> ... }
result.children() List rows prepStmt
result.attributes() Object firstRow prepStmt
result.depthFirst()
result.iterator() // see GDK hot tip
In the above, attributes can be fetched from each row by
index or by name
Shorthands for children, child, and attribute access:
db.eachRow('SELECT a,b ...'){ row ->
Shorthand Result println row[0] + ' ' + row.b
['elementName'] }
All child elements of that name
.elementName
[index] Child element by index Combine with GPath
['@attributeName'] List hits = db.rows('SELECT ...')
.'@attributeName' The attribute value stored under that name hits.grep{it.a > 0}
.@attributeName
DataSet
Reading the first ten titles from a blog: For easy DB operations without SQL
def url= 'http://'+ def dataSet = db.dataSet(tablename)
'www.groovyblogs.org/feed/rss' dataSet.add (
def rss = new XmlParser().parse(url) a: 1,
rss.channel.item.title[0..9]*.text() b: 'something'
)
dataSet.each { println it.a }
Writing XML
Groovy (Streaming-) MarkupBuilder allows you to produce dataSet.findAll { it.a < 2 }
proper XML with logic while keeping a declarative style. In the last statement, the expression in the findAll closure will
def b=new groovy.xml.MarkupBuilder() map directly to a SQL WHERE clause.
b.outermost {
simple() mETA PROgRAmmINg
'with-attr' a:1, b:'x', 'content'
10.times { count ->
nesting { nested count }
Categories
} Group of methods assigned at runtime to arbitrary classes
} that fulfill a common purpose. Applies to one thread. Scope is
limited to a closure.
SQL class IntCodec {
static String encode(Integer self){self.toString()}
static Integer decode(String self){self.toInteger()}
Connecting to the DB }
Getting a new Sql instance directly. For example, a HSQLDB use(IntCodec) {42.encode().decode()}
import groovy.sql.Sql ExpandoMetaClass
def db = Sql.newInstance( Same example but change applies to all threads and
'jdbc:hsqldb:mem:GInA', unlimited scope.
'user-name',
Integer.metaClass.encode << {delegate.toString()}
'password', String.metaClass.decode << {delegate.toInteger()}
'org.hsqldb.jdbcDriver') 42.encode().decode()
DZone, Inc. | www.dzone.com