SlideShare a Scribd company logo
1 of 87
SWITCHING FROM
            JAVA TO GROOVY
            Paul Woods
            mr.paul.woods@gmail.com
            @mr_paul_woods

9/26/2012
Table Of Contents
   Installing & Running      Multi-assign
   Hello World               Optionals
   Basics                      • Parenthesis

   List                        • Semicolons

   Maps                        • Returns

   Ranges                    Power Assert
   Operations                Meta Programming
   Closures                  Conclusion
Teaching Resources
   Mr. Haki - Great Groovy Tips Resource
     http://mrhaki.blogspot.com/

   How to do X in Groovy
     http://groovy-almanac.org/

   Share and Run Groovy Scripts
     http://groovyconsole.appspot.com/

   Learn Groovy by Fixing Failing Tests
     http://groovykoans.org/
Books
   Groovy In Action
   Programming Groovy
   Groovy Recipes
Groovy - Installing to Your
Computer
   Install Java JDK
   Set JAVA_HOME
   Make sure <javahome>/bin is in path
   Download Zip or installer package
       http://groovy.codehaus.org/Download
   Make sure <groovyhome>/bin is in path
   Test it
     java -version
     javac -version
     groovy -version
Groovy - Running on Web
Console
   http://groovyconsole.appspot.com/


   Allows you to execute groovy programs on a
    web-based console.
Hello World - Java
   Create a file called Hello.java
     public class Hello {
       public static void main(String[] args) {
               System.out.println("Hello Java World");
       }
    }

   Compile It
       javac Hello.java
   Run It
       java Hello
Hello World - Groovy
   Create a file called hello.groovy
     println   "Hello Groovy World!"
   Execute the file
     groovy    hello.groovy
Improvements over Java
   This is a groovy script file.
   No ceremony
     No Class
     No Public Method
     No System.out
     No Parenthesis
     No Semicolon


   * Of course, we can still add them if we
    want, and in some cases they are required.
Basics - Primitives
   There are no primitive types in Groovy. They
    are promoted to objects.
     inta=1
     println a.class
       class   java.lang.Integer


     float f = 2.5
     println f.class
       class   java.lang.Float
Basics - Types
   You are not forced to define the types, either. The
    Def keyword allows you to do this:
     def a = 1
     def b = 2.0
     def c = "Howdy"
     println a.class
     println b.class
     println c.class
         class java.lang.Integer
         class java.math.BigDecimal
         class java.lang.String
Basics - String Quotes
   Strings can use single quotes or double
    quotes.
     def a = "Hello World"
     def b = 'Goodbye'

     println a

     println b
       Hello
            World
       Goodbye
Basics - GStrings
   The GString type allows expressions to be
    evaluated inside a string. Simple
    variables/properties are prefixed with $. Full
    expressions are wrapped in ${}
     def first = "Paul"
     def last = "Woods“

     def a = 11

     def b = 22

     def fullname = "$first $last ${a + b}"

     println fullname
           Paul Woods 33
Basics - GStrings
   GStrings are not Strings.
   They are very similar and can be used almost
    anywhere a String can be used.
     Don‟t   use them as map keys.
Basic - GStrings - Double
Quotes
   GString uses double quote marks in order to
    evaluate expressions. Single quote marks are
    not evaluated.
     def age = 8
     def a = "I am $age years old"
     def b = 'I am $age years old'
     println "a = " + a
     println "b = " + b
      a  = I am 8 years old
       b = I am $age years old
Basics - String - Triple Quotes
   You can use triple quotes to keep from
    escaping quote marks.
     def a = """She said "Bring home some milk", but I
      forgot"""
     println a
         She said "Bring home some milk", but I forgot.
     def b = '''It's time to learn Groovy.'''
     println b
         It's time to learn Groovy.
Basics - Multi-line Strings
   You can easily define multi-line strings. Each line
    of the string is terminated with a newline - n
     def data = """
     This
     Is
    A
     Test"""
     println data
         This
         Is
        A
         Test
Basics - String Comparison
   Groovy overrides the == for case-sensitive
    String comparison.
   No more: if(0 == a.compareTo(b)) …

     def a = "abc"
     def b = "a" + "b" + "c"

     println a == b
       true
Basics - Script Files
   Groovy files can be either compiled into
    classes, or ran as script. Here is a script that
    defines a function, then executes it.
     Integer     sum(Integer a, Integer b) {
        a+b
    }

     println    "10 + 20 is " + sum(10,20)
         10   + 20 is 30
Basics - Groovy Truth
   Groovy truth tells how values are coerced into
    Booleans.
     non  zero numbers are true.
     zero numbers are false
     non-null objects are true
     null objects are false
     non-empty strings are true
     empty strings are false
     non-empty collections are true
     empty collections are false
Basics - Class - Map
Constructor
   A map default constructor is available to
    classes.
     class  Name {
        String first
        String last
    }

     def name = new Name(first:"Paul", last:"Woods")
     println name.dump()
         <Name@5c6ed020   first=Paul last=Woods>
Basics - Class - Getters &
Setters
   For all public fields, groovy makes the field
    private, and automatically creates a getter and
    setter for each.
   If you define a getter and/or setter, groovy
    doesn't define one.
   If you mark the field as readonly, only a getter
    will be created
Lists
   Groovy has a native syntax for lists. It uses
    square brackets [] to indicate a list.
   Define a empty list
     def   list = []
   Initialize a list with values
     def list = [ 1, 2, 3 ]
     println list
       [1,   2, 3]
Lists
   Lists are a normal java data type
     def list = []
     println list.class
       class   java.util.ArrayList
List Gotcha - Static Type
Checking
       The items in a list are non-typed.
       We add a Integer, BigDecimal, String and
        Date
           def a = [ 1, 2.3, "Abc", new Date()]
           println a
            [1, 2.3, Abc, Tue Sep 25 20:21:17 CDT 2012]
   Generics are compile-time checked. Groovy
    ignores them, with no syntax error
           List<Integer> b = [“A”, new Date()]
           println b
            [A, Tue Sep 25 20:22:10 CDT 2012]
List - Adding Elements
   Add elements to a list using left shift
     def  list = ['q', 'w', 'e']
     list << 'r' << 't' << 'y'
     println list
       [q,   w, e, r, t, y]
   Add a list to a list - use the plus operation
     def  list = ["a","b","c"]
     list += [1,2,3]
     println list
       [a,   b, c, 1, 2, 3]
List - Iterating 1
   Multiple ways to loop through the elements in a
    list.
   By For Colon
     def list = ['q', 'w', 'e', 'r', 't', 'y']
     for(def item : list) {
       println "by item : $item"
    }
         by item : q
         by item : w
         by item : e
         by item : r
         by item : t
         by item : y
List - Iterating 2
   By For in
     def list = ['q', 'w', 'e', 'r', 't', 'y']
     for(def item in list) {
     println "by item in : $item"
    }
        by item in : q
        by item in : w
        by item in : e
        by item in : r
        by item in : t
        by item in : y
List - Iterating 3
   Use the each method on list
     def list = ['q', 'w', 'e', 'r', 't', 'y']
     list.each { item ->
        println "by each : $item"
    }
         by each : q
         by each : w
         by each : e
         by each : r
         by each : t
         by each : y
List - Transform
   Transform a list into another list using the
    collect method. The results of the closure are
    appended in a new list.
     def list1 = [1,2,3,4,5]
     def list2 = list1.collect { it * 10 }

     println "list1=$list1"

     println "list2=$list2"
       list1=[1,2, 3, 4, 5]
       list2=[10, 20, 30, 40, 50]
List - Retrieving Elements
   Multiple ways to retrieve list elements
   def list = ['q', 'w', 'e', 'r', 't', 'y']
     println "element 0 : ${list.get(0)}"
     println "element 1 : ${list[1]}"
     println "elements 1,3,5 : ${list[1,3,5]}"
     println "elements 0..3 : ${list[0..3]}"
     println "last 3 elements : ${list[-3..-1]} "
         element 0 : q
         element 1 : w
         elements 1,3,5 : [w, r, y]
         elements 0..3 : [q, w, e, r]
         last 3 elements : [r, t, y]
List - Removing Elements
   Removing Elements
       def list = ["q", "w", "e", "r", "t", "y"]
       println list
       list.remove(0)
       println list
       list -= "e"
       println list
       list -= ["t", "r"]
       println list
           [q, w, e, r, t, y]
           [w, e, r, t, y]
           [w, r, t, y]
           [w, y]
List - Sorting 1
   Sorting Lists - By Default, the original list is
    modified.
     def original = ['q', 'w', 'e', 'r', 't', 'y']
     def sorted = original.sort()

     println "original = " + original

     println "sorted = " + sorted
       original
               = [e, q, r, t, w, y]
       sorted = [e, q, r, t, w, y]
List - Sorting 2
   Sorting Lists - sort(false) will not sort the
    original.
     def original = ['q', 'w', 'e', 'r', 't', 'y']
     def sorted = original.sort(false)

     println "original = " + original

     println "sorted = " + sorted
       original
               = [q, w, e, r, t, y]
       sorted = [e, q, r, t, w, y]
List - Unique 1
   Retrieving the unique elements.
   The list does not need to be sorted.
   The original list is modified.
     def original = ['a', 'b', 'c', 'a', 'b', 'c' ]
     def uniqued = original.unique()

     println "original = " + original

     println "uniqued = " + uniqued
       original
               = [a, b, c]
       uniqued = [a, b, c]
List - Unique 2
   Use .unique(false) to not modify the original.
     def original = ['a', 'b', 'c', 'a', 'b', 'c' ]
     def uniqued = original.unique(false)

     println "original = " + original

     println "uniqued = " + uniqued
       original
               = [a, b, c, a, b, c]
       uniqued = [a, b, c]
List - Find
   Finding a single element in a list
     def list = ['q', 'w', 'e', 'r', 't', 'y']
     def item1 = list.find { item -> item == 'w' }

     def item2 = list.find { item -> item == '12345' }

     println "find 1 : " + item1

     println "find 2 : " + item2
       find 1:w
       find 2 : null
List - FindAll
   Finding all matching elements in in a list
     def list = ['q', 'w', 'e', 'r', 't', 'y']
     def letters = list.findAll { it < 't' }

     println "findAll : $letters"
       findAll   : [q, e, r]
List - Every
   Returns true if the closure returns true for
    every item in the list.
     def list = [4,5,6]
     boolean result1 = list.every { item -> item < 10 }

     println "every item less than 10 : $result1"

     boolean result2 = list.every { item -> 0 == item%2
      }
     println "every item is even : $result2"
       every item less than 10 : true
       every item is even : false
List - Any
   Returns true if the closure returns true for any
    item in the list.
     def list = [4,5,6]
     boolean result1 = list.any { item -> item > 5 }
     println "contains atleast one item greater than 5 :
      $result1"
     boolean result2 = list.any { item -> 1 == item%2 }
     println "contains atleast one item that is odd :
      $result2"
       contains atleast one item greater than 5 : true
       contains atleast one item that is odd : true
List - Join
   convert list into a string by converting each
    element to a string (toString()) and inserting a
    delimiter between elements.
     def list = [ 'q','w','e','r','t','y']
     def result = list.join("-")

     println result

     println result.class
        q-w-e-r-t-y
        class   java.lang.String
List - Advanced 1
   Sorting by values in a Map
       list = [
          [first:"paul", last:"woods"],
          [first:"linda", last:"zinde"],
          [first:"alex", last:"zinde"],
          [first:"paul", last:"allen"]
       ]
       println "sorted by first : ${list.sort { it.first } }"
       println "sorted by last : ${list.sort { it.last } }"
           sorted by first :
            [[first:alex, last:zinde], [first:linda, last:zinde], [first:paul, last:wo
            ods], [first:paul, last:allen]]
           sorted by last :
            [[first:paul, last:allen], [first:paul, last:woods], [first:alex, last:zin
            de], [first:linda, last:zinde]]
List - Advanced 2
   list = [
              [first:"paul", last:"woods"],
              [first:"linda", last:"zinde"],
              [first:"alex", last:"zinde"],
              [first:"paul", last:"allen"]
   ]

   // sorting by a value in a map
   println "sorted by first : ${list.sort { it.first } }"
   println "sorted by last : ${list.sort { it.last } }"

   // sorting by 2 values

   def sorted = list.sort { x, y ->
      (x.last <=> y.last) ?: (x.first <=> y.first)
   }
   println "sort by last and first : ${sorted}"
List - Advanced 3
   Transform a list of lists to a
    quoted-field csv string                "first","last"
       def list = [
                                           "paul","woods"
           [ "first", "last" ],
           [ "paul", "woods"],            "linda","zinde"
           [ "linda", "zinde"],           "alex","zinde"
           [ "alex", "zinde"],
                                           "paul","allen"
           [ "paul", "allen"]
       ]
       def csv = list.collect { row ->
           row.collect { item ->
               ""$item""
           }.join(',')
       }.join('n')
       println csv
List - Mystery
   Why does this work?
     List<String>   z = new ArrayList<String>()
    z  << "A"
     z << 1

     z << new Date()

     println z



    ? because generics in java are checked at
     compile time, and groovy doesn't check
Map
   A map is defined using the [:] syntax
     def   name = [:]


   A map is a normal java data structure
     def name = [:]
     println name.getClass()
       class   java.util.LinkedHashMap
Map - Initialize with Data
   Create map
     def map = [first : "Paul",last : "Woods"]
     println map
       [first:Paul,   last:Woods]
   Tip - if you need iterate through your keys in
    order, do this:
     def   map = new TreeMap<String,String>()
Map - Add Data
   Add elements to a map
     def map = [:]
     map += [first : "Paul"]

     map.middle = "Alexander"

     map.put("last", "Woods")

     println map
       [first:Paul,   middle:Alexander, last:Woods]
Map - Iterating with For
   Looping through maps
       def map = [ first: "Paul", last: "Woods" ]
       for(keyValue in map) {
         println "keyValue = $keyValue"
         println "key       = $keyValue.key"
         println "value     = $keyValue.value"
       }
           keyValue = first=Paul
           key     = first
           value   = Paul
           keyValue = last=Woods
           key     = last
           value   = Woods
Map - Iterating with Each 1
   looping through maps
       def map = [ first: "Paul", last: "Woods" ]
       map.each { keyValue ->
         println "keyValue = $keyValue"
         println "key     = $keyValue.key"
         println "value = $keyValue.value"
       }
           keyValue = first=Paul
           key     = first
           value   = Paul
           keyValue = last=Woods
           key     = last
           value    = Woods
Map - Iterating with Each 2
   Looping through maps. Closure has 2
    parameters
     def
        map = [ first: "Paul", last: "Woods" ]
     map.each { key, value ->
     println "key = $key"
     println "value = $value"
    }
       key  = first
       value = Paul
       key = last
       value = Woods
Map - Retrieving elements
   retrieving elements
     def map = [ first : "Paul", last : "Woods" ]
     def key = "first"
     def val1 = map.first
     def val2 = map["first"]
     def val3 = map[key]
     def val4 = map."$key"                 val1 = Paul
     println "val1 = " + val1              val2 = Paul
     println "val2 = " + val2              val3 = Paul
     println "val3 = " + val3              val4 = Paul
     println "val4 = " + val4
Map - Removing Elements
   Removing elements from a map
     def map = [ first : "Paul", last : "Woods" ]
     map.remove('first')

     println map
       [last:Woods]
Map - Find
   finding elements
     def map = [ first : "Paul", last : "Woods"]
     def result1 = map.find { kv -> kv.value == "Woods"
      }
     println result1.getClass()

     println result1
       classjava.util.LinkedHashMap$Entry
       last=Woods
Map - FindAll
   finding elements
     def map = [ first : "Paul", last : "Woods"]
     def result2 = map.findAll { kv -> kv.key != "last" }

     println result2.getClass()

     println result2
       class   java.util.LinkedHashMap
       [first:Paul]
Range

   A Range is a data structure that contains the
    beginning and ending value of a sequence. It
    can iterate through the sequence, and
    determine if a value is inside or outside of the
    sequence
     def range = (1..5)
     println range

     println range.class
Range - Iteration - Step
   You can use the each method to loop through
    all of the values.
     defrange = (1..5)
     range.step(2) { println it }
      1
      3
      5
Range - Iteration - Step
   You can use the each method to loop through
    all of the values.
     defrange = (1..5)
     range.step(2) { println it }
      1
      3
      5
Range - Contains
   You can use the each method to loop through
    all of the values.
     def range = (1..5)
     println "contains 5 : " + range.contains(5)

     println "contains 7 : " + range.contains(7)
       contains 5 : true
       contains 7 : false
Range - Data Types
   Ranges can also work on other data
    types, including dates.
     def range2 = (new Date()-7 .. new Date())
     range2.each { date -> println date }
         Tue Sep 18 22:18:26 CDT 2012
         Wed Sep 19 22:18:26 CDT 2012
         Thu Sep 20 22:18:26 CDT 2012
         Fri Sep 21 22:18:26 CDT 2012
         Sat Sep 22 22:18:26 CDT 2012
         Sun Sep 23 22:18:26 CDT 2012
         Mon Sep 24 22:18:26 CDT 2012
         Tue Sep 25 22:18:26 CDT 2012
Operation - ?. subscript
   This operator checks if the value is null, and
    either returns null or calls the method and
    returns its result.
   This code fails with NPE
     def  list = [ 'a', 'b', null, 'c', 'd' ]
     list.each { item -> println item.toUpperCase() }
      A
      B
       Caught:java.lang.NullPointerException: Cannot
       invoke method toUpperCase() on null object
Operation - ?. subscript
   This code succeeds
     def  list = [ 'a', 'b', null, 'c', 'd' ]
     list.each { item -> println item?.toUpperCase() }
      A
      B
       null
      C
      D
Operation - ?: conditional - Elvis
   if object is false, return another object. else return
    the object
     def a = null
     def b = ""
     def c = "abc"
     println "null : " + (a ?: "it is false")
     println "empty : " + (b ?: "it is false")
     println "value : " + (c ?: "it is false")
         null : it is false
         empty : it is false
         value : abc
Operation - <=> - spaceship
   calls the .compareTo method
   returns -1 if a < b
   returns +1 if a > b
   returns 0 if a == b
     println "1 <=> 2 : " + (1 <=> 2)
     println "2 <=> 1 : " + (2 <=> 1)
     println "1 <=> 1 : " + (1 <=> 1)
      1  <=> 2 : -1
       2 <=> 1 : 1
       1 <=> 1 : 0
Closures - Introduction
   A closure is a block of code.
   Unlike methods, the closure is assigned to a
    object.
   A closure can be reassigned to another object.
   The scope of a method (the values it can
    access) is determined by who owns the
    closure (by default). The scope rules can be
    changed at runtime.
Closures - Create and Call
   Define a closure that adds numbers, and call it
     Closure    add = { a, b ->
        a+b
    }

     println   add(1,2)
        3
Closure - Zero Parameter
Syntax
   Syntax for zero parameter closures
     def  zero = { ->
        println "zero parameters"
    }

     zero.call()
         zero   parameters
Closure - One Parameter
Syntax
   Syntax for a one parameter closure.
     def one_a = {
       println "one parameter : $it"
    }
     def one_b = { a->
       println "one named parameter : $a"
    }
     one_a.call('alpha')
     one_b.call('beta')
         one parameter : alpha
         one named parameter : beta
Closure - Parameter Syntax
   Syntax for 2+ parameter closures
     def  two = { a, b ->
        println "two parameters : $a $b"
    }

     two.call('22',   '2222')
         two   parameters : 22 2222
Closure - Method Takes
Closure
   A method that takes a closure
       class Name {
           def first
           def modify(Closure closure) {
              closure.call this
           }
           String toString() {first}
       }
       def capitalizer = { Name name ->
           name.first = name.first.capitalize()
       }
       def paul = new Name(name:"paul")
       println "before = " + paul
       paul.modify capitalizer
       println "after = " + paul
           before = paul
           after = Paul
Closure - Delegate
   Delegate changes the scope of a closure
       class Name {
           def name = ""
       }
       def name1 = new Name(name:"Paul")
       def name2 = new Name(name:"Woods")

       def namePrinter = { ->
           println name
       }

       namePrinter.delegate = name1
       namePrinter()
       namePrinter.delegate = name2
       namePrinter()
           Paul
           Woods
MultiAssign
   Initialize or assign multiple variables with values from a list.
       def a
       def b
       (a, b) = [ 1, 2 ]
       def (c, d) = [ 3 , 4 ]

       println "a=$a"
       println "b=$b"
       println "c=$c"
       println "d=$d"
           a=1
           b=2
           c=3
           d=4
Optional
parenthesis, semicolons, and
returns
   In some situations, groovy allows you to
    remove parenthesis, semicolons and return
    statements.
Optional - Parenthesis 1
   No Arguments and no „get‟ prefix - () mandatory
       class Name {
         def first, last
         def print() { println first + " " + last }
         def printDelim(delim) { println first + delim + last }
         def getFullName() { return first + " " + last }
         def getTotal(delim) { return first + delim + last }
       }
       def name = new Name(first:"Paul", last:"Woods")

       name.print() // () required

           Paul Woods
Optional - Parenthesis 2
   One or more arguments and not referencing the return
    value - () optional
       class Name {
         def first, last
         def print() { println first + " " + last }
         def printDelim(delim) { println first + delim + last }
         def getFullName() { return first + " " + last }
         def getTotal(delim) { return first + delim + last }
       }
       def name = new Name(first:"Paul", last:"Woods")

       name.printDelim " " // () not required
           Paul Woods
Optional - Parenthesis 3

   The method has a „get‟ prefix, and no arguments. ()
    optional
       class Name {
         def first, last
         def print() { println first + " " + last }
         def printDelim(delim) { println first + delim + last }
         def getFullName() { return first + " " + last }
         def getTotal(delim) { return first + delim + last }
       }
       def name = new Name(first:"Paul", last:"Woods")

       println name.fullName // drop get prefix and ()
           Paul Woods
Optional - Parenthesis 4

   Method has „get‟ prefix and 1 or more arguments and using
    the return value. () mandatory
       class Name {
          def first, last
          def print() { println first + " " + last }
          def printDelim(delim) { println first + delim + last }
          def getFullName() { return first + " " + last }
          def getTotal(delim) { return first + delim + last }
       }

       def name = new Name(first:"Paul", last:"Woods")

       println name.getTotal(",") // () mandatory
           Paul Woods
Optional - Semicolons
   Semicolons are almost always optional
   Must be used if multiple statements on a single
    line.
     def a = 1
     def b = 2
     println a
     println b
     println a; println b
        1
        2
        1
        2
Optional - Returns - 1
   Returns are optional when the value to be
    returned is the last line of the method.
     def sum(a, b) {
       a+b
    }



     def sub(a, b) {
       def total = a + b
       total
    }
Optional - Returns - 2
   Returns are optional when the method is a if/else method. The value to be
    returned is the last line of each block, and the if/else is the bottom of the
    method.
       def choose(a, b, c) {
          if(a > 0) {
              b
          } else if(a < 0) {
              c
          } else {
              0
          }
       }
       println " 1 : " + choose( 1, 10, 20)
       println "-1 : " + choose(-1, 10, 20)
       println " 0 : " + choose( 0, 10, 20)
            1 : 10
           -1 : 20
            0:0
PowerAssert
   Power Assert - in a failed assert statement, groovy
    shows you the values of the objects.
       def map = [a: [b: [c: 2]]]
       assert 3 == map.a.b.c
           Assertion failed:

           assert 3 == map.a.b.c
                    | |    | | |
                    | |    | | 2
                    | |    | [c:2]
                    | |    [b:[c:2]]
                    | [a:[b:[c:2]]]
                    false
PowerAssert - Gotcha 1
   PowerAssert Gotcha - If the difference is
    leading/trailing white space, the assert won't display a
    difference.
       def a = "a"
       def b = "arn"
       assert a == b
           Assertion failed:
           assert a == b
                  | | |
                  a | a
                    false


   It fails, but you can't tell why
Meta Programming
   Groovy can dynamically modify the code of
    classes at runtime
MP - Add Method to Object
   Adding a method to a object
     String a = "a"
     String b = "b"
     a.metaClass.hashIt = { ->
       "#" + delegate + "#"
    }
     println a.hashIt()
     println b.hashIt()
         #a#
         Caught: groovy.lang.MissingMethodException: No signature
          of method: java.lang.String.hashIt() …
MP - Add Method to Class
   Adding a method to a class
     String  a = "a"
     String b = "b"
     String.metaClass.hashIt = { ->
     "#" + delegate + "#"
    }
     println a.hashIt()
     println b.hashIt()
       #a#
       #b#
MP - Add Static Method to
Class
   Adding a method to a class
     String  a = "a"
     String.metaClass.static.hashIt = { ->

     "#" + delegate + "#"

    }

     println a.hashIt()

     println String.hashIt()
       #a#
       #class   java.lang.String#
Conclusion
   Read the Groovy JDK to see what Groovy added to the java classes.
       http://groovy.codehaus.org/groovy-jdk/
   Read about the groovy transformation annotations
       http://groovy.codehaus.org/gapi/index.html?groovy/transform/ToString.html
   Try Grails - Groovy / Spring / Hibernate WebApp
       http://grails.org/
   Try Gradle - Groovy Build Automation
       http://gradle.org/
   Try Gaelyk - Groovy on Google AppServer
       http://gaelyk.appspot.com/
   Try Griffon - Groovy desktop java applications
       http://griffon.codehaus.org/
   Try Gpars - Concurrency with Groovy
       http://gpars.codehaus.org/
   Abstract Syntax Trees
       http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations

More Related Content

What's hot

Template Haskell とか
Template Haskell とかTemplate Haskell とか
Template Haskell とかHiromi Ishii
 
Functional Error Handling with Cats
Functional Error Handling with CatsFunctional Error Handling with Cats
Functional Error Handling with CatsMark Canlas
 
Invertible-syntax 入門
Invertible-syntax 入門Invertible-syntax 入門
Invertible-syntax 入門Hiromi Ishii
 
Learn python - for beginners - part-2
Learn python - for beginners - part-2Learn python - for beginners - part-2
Learn python - for beginners - part-2RajKumar Rampelli
 
Scala in a Java 8 World
Scala in a Java 8 WorldScala in a Java 8 World
Scala in a Java 8 WorldDaniel Blyth
 
Forget about loops
Forget about loopsForget about loops
Forget about loopsDušan Kasan
 
Jquery 13 cheatsheet_v1
Jquery 13 cheatsheet_v1Jquery 13 cheatsheet_v1
Jquery 13 cheatsheet_v1ilesh raval
 
Jquery 1.3 cheatsheet_v1
Jquery 1.3 cheatsheet_v1Jquery 1.3 cheatsheet_v1
Jquery 1.3 cheatsheet_v1Sultan Khan
 
Python fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuanPython fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuanWei-Yuan Chang
 
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kirill Rozov
 
Python Ireland Nov 2010 Talk: Unit Testing
Python Ireland Nov 2010 Talk: Unit TestingPython Ireland Nov 2010 Talk: Unit Testing
Python Ireland Nov 2010 Talk: Unit TestingPython Ireland
 
Python легко и просто. Красиво решаем повседневные задачи
Python легко и просто. Красиво решаем повседневные задачиPython легко и просто. Красиво решаем повседневные задачи
Python легко и просто. Красиво решаем повседневные задачиMaxim Kulsha
 
Python and sysadmin I
Python and sysadmin IPython and sysadmin I
Python and sysadmin IGuixing Bai
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 

What's hot (17)

Template Haskell とか
Template Haskell とかTemplate Haskell とか
Template Haskell とか
 
Functional Error Handling with Cats
Functional Error Handling with CatsFunctional Error Handling with Cats
Functional Error Handling with Cats
 
Invertible-syntax 入門
Invertible-syntax 入門Invertible-syntax 入門
Invertible-syntax 入門
 
Learn python - for beginners - part-2
Learn python - for beginners - part-2Learn python - for beginners - part-2
Learn python - for beginners - part-2
 
Scala in a Java 8 World
Scala in a Java 8 WorldScala in a Java 8 World
Scala in a Java 8 World
 
Forget about loops
Forget about loopsForget about loops
Forget about loops
 
Jquery 13 cheatsheet_v1
Jquery 13 cheatsheet_v1Jquery 13 cheatsheet_v1
Jquery 13 cheatsheet_v1
 
Jquery 1.3 cheatsheet_v1
Jquery 1.3 cheatsheet_v1Jquery 1.3 cheatsheet_v1
Jquery 1.3 cheatsheet_v1
 
Five
FiveFive
Five
 
Python fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuanPython fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuan
 
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3
 
Python Ireland Nov 2010 Talk: Unit Testing
Python Ireland Nov 2010 Talk: Unit TestingPython Ireland Nov 2010 Talk: Unit Testing
Python Ireland Nov 2010 Talk: Unit Testing
 
Python легко и просто. Красиво решаем повседневные задачи
Python легко и просто. Красиво решаем повседневные задачиPython легко и просто. Красиво решаем повседневные задачи
Python легко и просто. Красиво решаем повседневные задачи
 
Groovy unleashed
Groovy unleashed Groovy unleashed
Groovy unleashed
 
Python and sysadmin I
Python and sysadmin IPython and sysadmin I
Python and sysadmin I
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Python - Lecture 3
Python - Lecture 3Python - Lecture 3
Python - Lecture 3
 

Viewers also liked

Online Business Trends beyond 2010
Online Business Trends beyond 2010Online Business Trends beyond 2010
Online Business Trends beyond 2010Jesper Åström
 
Lyddie: Unit3 lesson5
Lyddie: Unit3 lesson5Lyddie: Unit3 lesson5
Lyddie: Unit3 lesson5Terri Weiss
 
Google Androidの現在と近未来 ~マッシュアップにより変革するもの~
Google Androidの現在と近未来 ~マッシュアップにより変革するもの~Google Androidの現在と近未来 ~マッシュアップにより変革するもの~
Google Androidの現在と近未来 ~マッシュアップにより変革するもの~shimay
 
River Otter by Brennan
River Otter by BrennanRiver Otter by Brennan
River Otter by Brennanvebrya
 
AHA CHDO - EE in HOME Workshop
AHA CHDO - EE in HOME WorkshopAHA CHDO - EE in HOME Workshop
AHA CHDO - EE in HOME WorkshopICF_HCD
 
Making The Connection Workshop Presentation 11 28 2007
Making The Connection Workshop Presentation 11 28 2007Making The Connection Workshop Presentation 11 28 2007
Making The Connection Workshop Presentation 11 28 2007guest7fa781
 
Zima sisljavic
Zima sisljavicZima sisljavic
Zima sisljavicGavranica
 
Хорошо ли работают Ваши менеджеры по продажам?
Хорошо ли работают Ваши менеджеры по продажам?Хорошо ли работают Ваши менеджеры по продажам?
Хорошо ли работают Ваши менеджеры по продажам?Mikhail Grafsky
 
Zvonci dobrega srca
Zvonci dobrega srcaZvonci dobrega srca
Zvonci dobrega srcaGavranica
 
Daily Lecture And Discussions
Daily Lecture And DiscussionsDaily Lecture And Discussions
Daily Lecture And Discussionsbsutton
 
Microsite – Macro Idea
Microsite – Macro IdeaMicrosite – Macro Idea
Microsite – Macro IdeaMaria Podolyak
 
Understanding Open Source
Understanding Open SourceUnderstanding Open Source
Understanding Open SourceKinshuk Sunil
 
CfP dataTEL SI at Journal IJTEL deadline 25.10.2011
CfP dataTEL SI at Journal IJTEL deadline 25.10.2011CfP dataTEL SI at Journal IJTEL deadline 25.10.2011
CfP dataTEL SI at Journal IJTEL deadline 25.10.2011Hendrik Drachsler
 
Lyddie: Unit3 lesson3
Lyddie:  Unit3 lesson3Lyddie:  Unit3 lesson3
Lyddie: Unit3 lesson3Terri Weiss
 
Little Ones Learning Math Using Technology
Little Ones Learning Math Using TechnologyLittle Ones Learning Math Using Technology
Little Ones Learning Math Using TechnologyJennifer Orr
 
Team Up with Families: Using Technology to Build Bridges
Team Up with Families: Using Technology to Build BridgesTeam Up with Families: Using Technology to Build Bridges
Team Up with Families: Using Technology to Build BridgesJennifer Orr
 
Data - Internet -> Information: Doing effective research over the Internet
Data - Internet -> Information: Doing effective research over the InternetData - Internet -> Information: Doing effective research over the Internet
Data - Internet -> Information: Doing effective research over the InternetKinshuk Sunil
 

Viewers also liked (20)

Online Business Trends beyond 2010
Online Business Trends beyond 2010Online Business Trends beyond 2010
Online Business Trends beyond 2010
 
Lyddie: Unit3 lesson5
Lyddie: Unit3 lesson5Lyddie: Unit3 lesson5
Lyddie: Unit3 lesson5
 
Google Androidの現在と近未来 ~マッシュアップにより変革するもの~
Google Androidの現在と近未来 ~マッシュアップにより変革するもの~Google Androidの現在と近未来 ~マッシュアップにより変革するもの~
Google Androidの現在と近未来 ~マッシュアップにより変革するもの~
 
River Otter by Brennan
River Otter by BrennanRiver Otter by Brennan
River Otter by Brennan
 
AHA CHDO - EE in HOME Workshop
AHA CHDO - EE in HOME WorkshopAHA CHDO - EE in HOME Workshop
AHA CHDO - EE in HOME Workshop
 
Making The Connection Workshop Presentation 11 28 2007
Making The Connection Workshop Presentation 11 28 2007Making The Connection Workshop Presentation 11 28 2007
Making The Connection Workshop Presentation 11 28 2007
 
Journey To The East Part 2
Journey To The East Part 2Journey To The East Part 2
Journey To The East Part 2
 
Zima sisljavic
Zima sisljavicZima sisljavic
Zima sisljavic
 
Unit3 lesson1
Unit3 lesson1Unit3 lesson1
Unit3 lesson1
 
Хорошо ли работают Ваши менеджеры по продажам?
Хорошо ли работают Ваши менеджеры по продажам?Хорошо ли работают Ваши менеджеры по продажам?
Хорошо ли работают Ваши менеджеры по продажам?
 
Ss Project
Ss ProjectSs Project
Ss Project
 
Zvonci dobrega srca
Zvonci dobrega srcaZvonci dobrega srca
Zvonci dobrega srca
 
Daily Lecture And Discussions
Daily Lecture And DiscussionsDaily Lecture And Discussions
Daily Lecture And Discussions
 
Microsite – Macro Idea
Microsite – Macro IdeaMicrosite – Macro Idea
Microsite – Macro Idea
 
Understanding Open Source
Understanding Open SourceUnderstanding Open Source
Understanding Open Source
 
CfP dataTEL SI at Journal IJTEL deadline 25.10.2011
CfP dataTEL SI at Journal IJTEL deadline 25.10.2011CfP dataTEL SI at Journal IJTEL deadline 25.10.2011
CfP dataTEL SI at Journal IJTEL deadline 25.10.2011
 
Lyddie: Unit3 lesson3
Lyddie:  Unit3 lesson3Lyddie:  Unit3 lesson3
Lyddie: Unit3 lesson3
 
Little Ones Learning Math Using Technology
Little Ones Learning Math Using TechnologyLittle Ones Learning Math Using Technology
Little Ones Learning Math Using Technology
 
Team Up with Families: Using Technology to Build Bridges
Team Up with Families: Using Technology to Build BridgesTeam Up with Families: Using Technology to Build Bridges
Team Up with Families: Using Technology to Build Bridges
 
Data - Internet -> Information: Doing effective research over the Internet
Data - Internet -> Information: Doing effective research over the InternetData - Internet -> Information: Doing effective research over the Internet
Data - Internet -> Information: Doing effective research over the Internet
 

Similar to Switching from java to groovy

Groovy presentation
Groovy presentationGroovy presentation
Groovy presentationManav Prasad
 
Introductionto fp with groovy
Introductionto fp with groovyIntroductionto fp with groovy
Introductionto fp with groovyIsuru Samaraweera
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language TriviaNikita Popov
 
Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!Paige Bailey
 
python beginner talk slide
python beginner talk slidepython beginner talk slide
python beginner talk slidejonycse
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayUtkarsh Sengar
 
An introduction to property-based testing
An introduction to property-based testingAn introduction to property-based testing
An introduction to property-based testingVincent Pradeilles
 
Python_Cheat_Sheet_Keywords_1664634397.pdf
Python_Cheat_Sheet_Keywords_1664634397.pdfPython_Cheat_Sheet_Keywords_1664634397.pdf
Python_Cheat_Sheet_Keywords_1664634397.pdfsagar414433
 
Python_Cheat_Sheet_Keywords_1664634397.pdf
Python_Cheat_Sheet_Keywords_1664634397.pdfPython_Cheat_Sheet_Keywords_1664634397.pdf
Python_Cheat_Sheet_Keywords_1664634397.pdfsagar414433
 
A limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyA limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyVysakh Sreenivasan
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with GroovyArturo Herrero
 
Scripting3
Scripting3Scripting3
Scripting3Nao Dara
 
File handling in pythan.pptx
File handling in pythan.pptxFile handling in pythan.pptx
File handling in pythan.pptxNawalKishore38
 
The Great Scala Makeover
The Great Scala MakeoverThe Great Scala Makeover
The Great Scala MakeoverGarth Gilmour
 
Introduction to Gremlin
Introduction to GremlinIntroduction to Gremlin
Introduction to GremlinMax De Marzi
 

Similar to Switching from java to groovy (20)

Groovy presentation
Groovy presentationGroovy presentation
Groovy presentation
 
Introductionto fp with groovy
Introductionto fp with groovyIntroductionto fp with groovy
Introductionto fp with groovy
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language Trivia
 
Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!
 
python beginner talk slide
python beginner talk slidepython beginner talk slide
python beginner talk slide
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard Way
 
Groovy intro for OUDL
Groovy intro for OUDLGroovy intro for OUDL
Groovy intro for OUDL
 
An introduction to property-based testing
An introduction to property-based testingAn introduction to property-based testing
An introduction to property-based testing
 
Python_Cheat_Sheet_Keywords_1664634397.pdf
Python_Cheat_Sheet_Keywords_1664634397.pdfPython_Cheat_Sheet_Keywords_1664634397.pdf
Python_Cheat_Sheet_Keywords_1664634397.pdf
 
Python_Cheat_Sheet_Keywords_1664634397.pdf
Python_Cheat_Sheet_Keywords_1664634397.pdfPython_Cheat_Sheet_Keywords_1664634397.pdf
Python_Cheat_Sheet_Keywords_1664634397.pdf
 
A limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyA limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced Ruby
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Scripting3
Scripting3Scripting3
Scripting3
 
Chapter 2 wbp.pptx
Chapter 2 wbp.pptxChapter 2 wbp.pptx
Chapter 2 wbp.pptx
 
File handling in pythan.pptx
File handling in pythan.pptxFile handling in pythan.pptx
File handling in pythan.pptx
 
Groovy
GroovyGroovy
Groovy
 
P3 2018 python_regexes
P3 2018 python_regexesP3 2018 python_regexes
P3 2018 python_regexes
 
Python Basic
Python BasicPython Basic
Python Basic
 
The Great Scala Makeover
The Great Scala MakeoverThe Great Scala Makeover
The Great Scala Makeover
 
Introduction to Gremlin
Introduction to GremlinIntroduction to Gremlin
Introduction to Gremlin
 

Recently uploaded

Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 

Recently uploaded (20)

Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 

Switching from java to groovy

  • 1. SWITCHING FROM JAVA TO GROOVY Paul Woods mr.paul.woods@gmail.com @mr_paul_woods 9/26/2012
  • 2. Table Of Contents  Installing & Running  Multi-assign  Hello World  Optionals  Basics • Parenthesis  List • Semicolons  Maps • Returns  Ranges  Power Assert  Operations  Meta Programming  Closures  Conclusion
  • 3. Teaching Resources  Mr. Haki - Great Groovy Tips Resource  http://mrhaki.blogspot.com/  How to do X in Groovy  http://groovy-almanac.org/  Share and Run Groovy Scripts  http://groovyconsole.appspot.com/  Learn Groovy by Fixing Failing Tests  http://groovykoans.org/
  • 4. Books  Groovy In Action  Programming Groovy  Groovy Recipes
  • 5. Groovy - Installing to Your Computer  Install Java JDK  Set JAVA_HOME  Make sure <javahome>/bin is in path  Download Zip or installer package  http://groovy.codehaus.org/Download  Make sure <groovyhome>/bin is in path  Test it  java -version  javac -version  groovy -version
  • 6. Groovy - Running on Web Console  http://groovyconsole.appspot.com/  Allows you to execute groovy programs on a web-based console.
  • 7. Hello World - Java  Create a file called Hello.java  public class Hello {  public static void main(String[] args) {  System.out.println("Hello Java World");  } }  Compile It  javac Hello.java  Run It  java Hello
  • 8. Hello World - Groovy  Create a file called hello.groovy  println "Hello Groovy World!"  Execute the file  groovy hello.groovy
  • 9. Improvements over Java  This is a groovy script file.  No ceremony  No Class  No Public Method  No System.out  No Parenthesis  No Semicolon  * Of course, we can still add them if we want, and in some cases they are required.
  • 10. Basics - Primitives  There are no primitive types in Groovy. They are promoted to objects.  inta=1  println a.class  class java.lang.Integer  float f = 2.5  println f.class  class java.lang.Float
  • 11. Basics - Types  You are not forced to define the types, either. The Def keyword allows you to do this:  def a = 1  def b = 2.0  def c = "Howdy"  println a.class  println b.class  println c.class  class java.lang.Integer  class java.math.BigDecimal  class java.lang.String
  • 12. Basics - String Quotes  Strings can use single quotes or double quotes.  def a = "Hello World"  def b = 'Goodbye'  println a  println b  Hello World  Goodbye
  • 13. Basics - GStrings  The GString type allows expressions to be evaluated inside a string. Simple variables/properties are prefixed with $. Full expressions are wrapped in ${}  def first = "Paul"  def last = "Woods“  def a = 11  def b = 22  def fullname = "$first $last ${a + b}"  println fullname  Paul Woods 33
  • 14. Basics - GStrings  GStrings are not Strings.  They are very similar and can be used almost anywhere a String can be used.  Don‟t use them as map keys.
  • 15. Basic - GStrings - Double Quotes  GString uses double quote marks in order to evaluate expressions. Single quote marks are not evaluated.  def age = 8  def a = "I am $age years old"  def b = 'I am $age years old'  println "a = " + a  println "b = " + b a = I am 8 years old  b = I am $age years old
  • 16. Basics - String - Triple Quotes  You can use triple quotes to keep from escaping quote marks.  def a = """She said "Bring home some milk", but I forgot"""  println a  She said "Bring home some milk", but I forgot.  def b = '''It's time to learn Groovy.'''  println b  It's time to learn Groovy.
  • 17. Basics - Multi-line Strings  You can easily define multi-line strings. Each line of the string is terminated with a newline - n  def data = """  This  Is A  Test"""  println data  This  Is A  Test
  • 18. Basics - String Comparison  Groovy overrides the == for case-sensitive String comparison.  No more: if(0 == a.compareTo(b)) …  def a = "abc"  def b = "a" + "b" + "c"  println a == b  true
  • 19. Basics - Script Files  Groovy files can be either compiled into classes, or ran as script. Here is a script that defines a function, then executes it.  Integer sum(Integer a, Integer b) {  a+b }  println "10 + 20 is " + sum(10,20)  10 + 20 is 30
  • 20. Basics - Groovy Truth  Groovy truth tells how values are coerced into Booleans.  non zero numbers are true.  zero numbers are false  non-null objects are true  null objects are false  non-empty strings are true  empty strings are false  non-empty collections are true  empty collections are false
  • 21. Basics - Class - Map Constructor  A map default constructor is available to classes.  class Name {  String first  String last }  def name = new Name(first:"Paul", last:"Woods")  println name.dump()  <Name@5c6ed020 first=Paul last=Woods>
  • 22. Basics - Class - Getters & Setters  For all public fields, groovy makes the field private, and automatically creates a getter and setter for each.  If you define a getter and/or setter, groovy doesn't define one.  If you mark the field as readonly, only a getter will be created
  • 23. Lists  Groovy has a native syntax for lists. It uses square brackets [] to indicate a list.  Define a empty list  def list = []  Initialize a list with values  def list = [ 1, 2, 3 ]  println list  [1, 2, 3]
  • 24. Lists  Lists are a normal java data type  def list = []  println list.class  class java.util.ArrayList
  • 25. List Gotcha - Static Type Checking  The items in a list are non-typed.  We add a Integer, BigDecimal, String and Date  def a = [ 1, 2.3, "Abc", new Date()]  println a  [1, 2.3, Abc, Tue Sep 25 20:21:17 CDT 2012]  Generics are compile-time checked. Groovy ignores them, with no syntax error  List<Integer> b = [“A”, new Date()]  println b  [A, Tue Sep 25 20:22:10 CDT 2012]
  • 26. List - Adding Elements  Add elements to a list using left shift  def list = ['q', 'w', 'e']  list << 'r' << 't' << 'y'  println list  [q, w, e, r, t, y]  Add a list to a list - use the plus operation  def list = ["a","b","c"]  list += [1,2,3]  println list  [a, b, c, 1, 2, 3]
  • 27. List - Iterating 1  Multiple ways to loop through the elements in a list.  By For Colon  def list = ['q', 'w', 'e', 'r', 't', 'y']  for(def item : list) {  println "by item : $item" }  by item : q  by item : w  by item : e  by item : r  by item : t  by item : y
  • 28. List - Iterating 2  By For in  def list = ['q', 'w', 'e', 'r', 't', 'y']  for(def item in list) {  println "by item in : $item" }  by item in : q  by item in : w  by item in : e  by item in : r  by item in : t  by item in : y
  • 29. List - Iterating 3  Use the each method on list  def list = ['q', 'w', 'e', 'r', 't', 'y']  list.each { item ->  println "by each : $item" }  by each : q  by each : w  by each : e  by each : r  by each : t  by each : y
  • 30. List - Transform  Transform a list into another list using the collect method. The results of the closure are appended in a new list.  def list1 = [1,2,3,4,5]  def list2 = list1.collect { it * 10 }  println "list1=$list1"  println "list2=$list2"  list1=[1,2, 3, 4, 5]  list2=[10, 20, 30, 40, 50]
  • 31. List - Retrieving Elements  Multiple ways to retrieve list elements  def list = ['q', 'w', 'e', 'r', 't', 'y']  println "element 0 : ${list.get(0)}"  println "element 1 : ${list[1]}"  println "elements 1,3,5 : ${list[1,3,5]}"  println "elements 0..3 : ${list[0..3]}"  println "last 3 elements : ${list[-3..-1]} "  element 0 : q  element 1 : w  elements 1,3,5 : [w, r, y]  elements 0..3 : [q, w, e, r]  last 3 elements : [r, t, y]
  • 32. List - Removing Elements  Removing Elements  def list = ["q", "w", "e", "r", "t", "y"]  println list  list.remove(0)  println list  list -= "e"  println list  list -= ["t", "r"]  println list  [q, w, e, r, t, y]  [w, e, r, t, y]  [w, r, t, y]  [w, y]
  • 33. List - Sorting 1  Sorting Lists - By Default, the original list is modified.  def original = ['q', 'w', 'e', 'r', 't', 'y']  def sorted = original.sort()  println "original = " + original  println "sorted = " + sorted  original = [e, q, r, t, w, y]  sorted = [e, q, r, t, w, y]
  • 34. List - Sorting 2  Sorting Lists - sort(false) will not sort the original.  def original = ['q', 'w', 'e', 'r', 't', 'y']  def sorted = original.sort(false)  println "original = " + original  println "sorted = " + sorted  original = [q, w, e, r, t, y]  sorted = [e, q, r, t, w, y]
  • 35. List - Unique 1  Retrieving the unique elements.  The list does not need to be sorted.  The original list is modified.  def original = ['a', 'b', 'c', 'a', 'b', 'c' ]  def uniqued = original.unique()  println "original = " + original  println "uniqued = " + uniqued  original = [a, b, c]  uniqued = [a, b, c]
  • 36. List - Unique 2  Use .unique(false) to not modify the original.  def original = ['a', 'b', 'c', 'a', 'b', 'c' ]  def uniqued = original.unique(false)  println "original = " + original  println "uniqued = " + uniqued  original = [a, b, c, a, b, c]  uniqued = [a, b, c]
  • 37. List - Find  Finding a single element in a list  def list = ['q', 'w', 'e', 'r', 't', 'y']  def item1 = list.find { item -> item == 'w' }  def item2 = list.find { item -> item == '12345' }  println "find 1 : " + item1  println "find 2 : " + item2  find 1:w  find 2 : null
  • 38. List - FindAll  Finding all matching elements in in a list  def list = ['q', 'w', 'e', 'r', 't', 'y']  def letters = list.findAll { it < 't' }  println "findAll : $letters"  findAll : [q, e, r]
  • 39. List - Every  Returns true if the closure returns true for every item in the list.  def list = [4,5,6]  boolean result1 = list.every { item -> item < 10 }  println "every item less than 10 : $result1"  boolean result2 = list.every { item -> 0 == item%2 }  println "every item is even : $result2"  every item less than 10 : true  every item is even : false
  • 40. List - Any  Returns true if the closure returns true for any item in the list.  def list = [4,5,6]  boolean result1 = list.any { item -> item > 5 }  println "contains atleast one item greater than 5 : $result1"  boolean result2 = list.any { item -> 1 == item%2 }  println "contains atleast one item that is odd : $result2"  contains atleast one item greater than 5 : true  contains atleast one item that is odd : true
  • 41. List - Join  convert list into a string by converting each element to a string (toString()) and inserting a delimiter between elements.  def list = [ 'q','w','e','r','t','y']  def result = list.join("-")  println result  println result.class  q-w-e-r-t-y  class java.lang.String
  • 42. List - Advanced 1  Sorting by values in a Map  list = [  [first:"paul", last:"woods"],  [first:"linda", last:"zinde"],  [first:"alex", last:"zinde"],  [first:"paul", last:"allen"]  ]  println "sorted by first : ${list.sort { it.first } }"  println "sorted by last : ${list.sort { it.last } }"  sorted by first : [[first:alex, last:zinde], [first:linda, last:zinde], [first:paul, last:wo ods], [first:paul, last:allen]]  sorted by last : [[first:paul, last:allen], [first:paul, last:woods], [first:alex, last:zin de], [first:linda, last:zinde]]
  • 43. List - Advanced 2  list = [  [first:"paul", last:"woods"],  [first:"linda", last:"zinde"],  [first:"alex", last:"zinde"],  [first:"paul", last:"allen"]  ]  // sorting by a value in a map  println "sorted by first : ${list.sort { it.first } }"  println "sorted by last : ${list.sort { it.last } }"  // sorting by 2 values  def sorted = list.sort { x, y ->  (x.last <=> y.last) ?: (x.first <=> y.first)  }  println "sort by last and first : ${sorted}"
  • 44. List - Advanced 3  Transform a list of lists to a quoted-field csv string  "first","last"  def list = [  "paul","woods"  [ "first", "last" ],  [ "paul", "woods"],  "linda","zinde"  [ "linda", "zinde"],  "alex","zinde"  [ "alex", "zinde"],  "paul","allen"  [ "paul", "allen"]  ]  def csv = list.collect { row ->  row.collect { item ->  ""$item""  }.join(',')  }.join('n')  println csv
  • 45. List - Mystery  Why does this work?  List<String> z = new ArrayList<String>() z << "A"  z << 1  z << new Date()  println z ? because generics in java are checked at compile time, and groovy doesn't check
  • 46. Map  A map is defined using the [:] syntax  def name = [:]  A map is a normal java data structure  def name = [:]  println name.getClass()  class java.util.LinkedHashMap
  • 47. Map - Initialize with Data  Create map  def map = [first : "Paul",last : "Woods"]  println map  [first:Paul, last:Woods]  Tip - if you need iterate through your keys in order, do this:  def map = new TreeMap<String,String>()
  • 48. Map - Add Data  Add elements to a map  def map = [:]  map += [first : "Paul"]  map.middle = "Alexander"  map.put("last", "Woods")  println map  [first:Paul, middle:Alexander, last:Woods]
  • 49. Map - Iterating with For  Looping through maps  def map = [ first: "Paul", last: "Woods" ]  for(keyValue in map) {  println "keyValue = $keyValue"  println "key = $keyValue.key"  println "value = $keyValue.value"  }  keyValue = first=Paul  key = first  value = Paul  keyValue = last=Woods  key = last  value = Woods
  • 50. Map - Iterating with Each 1  looping through maps  def map = [ first: "Paul", last: "Woods" ]  map.each { keyValue ->  println "keyValue = $keyValue"  println "key = $keyValue.key"  println "value = $keyValue.value"  }  keyValue = first=Paul  key = first  value = Paul  keyValue = last=Woods  key = last  value = Woods
  • 51. Map - Iterating with Each 2  Looping through maps. Closure has 2 parameters  def map = [ first: "Paul", last: "Woods" ]  map.each { key, value ->  println "key = $key"  println "value = $value" }  key = first  value = Paul  key = last  value = Woods
  • 52. Map - Retrieving elements  retrieving elements  def map = [ first : "Paul", last : "Woods" ]  def key = "first"  def val1 = map.first  def val2 = map["first"]  def val3 = map[key]  def val4 = map."$key"  val1 = Paul  println "val1 = " + val1  val2 = Paul  println "val2 = " + val2  val3 = Paul  println "val3 = " + val3  val4 = Paul  println "val4 = " + val4
  • 53. Map - Removing Elements  Removing elements from a map  def map = [ first : "Paul", last : "Woods" ]  map.remove('first')  println map  [last:Woods]
  • 54. Map - Find  finding elements  def map = [ first : "Paul", last : "Woods"]  def result1 = map.find { kv -> kv.value == "Woods" }  println result1.getClass()  println result1  classjava.util.LinkedHashMap$Entry  last=Woods
  • 55. Map - FindAll  finding elements  def map = [ first : "Paul", last : "Woods"]  def result2 = map.findAll { kv -> kv.key != "last" }  println result2.getClass()  println result2  class java.util.LinkedHashMap  [first:Paul]
  • 56. Range  A Range is a data structure that contains the beginning and ending value of a sequence. It can iterate through the sequence, and determine if a value is inside or outside of the sequence  def range = (1..5)  println range  println range.class
  • 57. Range - Iteration - Step  You can use the each method to loop through all of the values.  defrange = (1..5)  range.step(2) { println it } 1 3 5
  • 58. Range - Iteration - Step  You can use the each method to loop through all of the values.  defrange = (1..5)  range.step(2) { println it } 1 3 5
  • 59. Range - Contains  You can use the each method to loop through all of the values.  def range = (1..5)  println "contains 5 : " + range.contains(5)  println "contains 7 : " + range.contains(7)  contains 5 : true  contains 7 : false
  • 60. Range - Data Types  Ranges can also work on other data types, including dates.  def range2 = (new Date()-7 .. new Date())  range2.each { date -> println date }  Tue Sep 18 22:18:26 CDT 2012  Wed Sep 19 22:18:26 CDT 2012  Thu Sep 20 22:18:26 CDT 2012  Fri Sep 21 22:18:26 CDT 2012  Sat Sep 22 22:18:26 CDT 2012  Sun Sep 23 22:18:26 CDT 2012  Mon Sep 24 22:18:26 CDT 2012  Tue Sep 25 22:18:26 CDT 2012
  • 61. Operation - ?. subscript  This operator checks if the value is null, and either returns null or calls the method and returns its result.  This code fails with NPE  def list = [ 'a', 'b', null, 'c', 'd' ]  list.each { item -> println item.toUpperCase() } A B  Caught:java.lang.NullPointerException: Cannot invoke method toUpperCase() on null object
  • 62. Operation - ?. subscript  This code succeeds  def list = [ 'a', 'b', null, 'c', 'd' ]  list.each { item -> println item?.toUpperCase() } A B  null C D
  • 63. Operation - ?: conditional - Elvis  if object is false, return another object. else return the object  def a = null  def b = ""  def c = "abc"  println "null : " + (a ?: "it is false")  println "empty : " + (b ?: "it is false")  println "value : " + (c ?: "it is false")  null : it is false  empty : it is false  value : abc
  • 64. Operation - <=> - spaceship  calls the .compareTo method  returns -1 if a < b  returns +1 if a > b  returns 0 if a == b  println "1 <=> 2 : " + (1 <=> 2)  println "2 <=> 1 : " + (2 <=> 1)  println "1 <=> 1 : " + (1 <=> 1) 1 <=> 2 : -1  2 <=> 1 : 1  1 <=> 1 : 0
  • 65. Closures - Introduction  A closure is a block of code.  Unlike methods, the closure is assigned to a object.  A closure can be reassigned to another object.  The scope of a method (the values it can access) is determined by who owns the closure (by default). The scope rules can be changed at runtime.
  • 66. Closures - Create and Call  Define a closure that adds numbers, and call it  Closure add = { a, b ->  a+b }  println add(1,2) 3
  • 67. Closure - Zero Parameter Syntax  Syntax for zero parameter closures  def zero = { ->  println "zero parameters" }  zero.call()  zero parameters
  • 68. Closure - One Parameter Syntax  Syntax for a one parameter closure.  def one_a = {  println "one parameter : $it" }  def one_b = { a->  println "one named parameter : $a" }  one_a.call('alpha')  one_b.call('beta')  one parameter : alpha  one named parameter : beta
  • 69. Closure - Parameter Syntax  Syntax for 2+ parameter closures  def two = { a, b ->  println "two parameters : $a $b" }  two.call('22', '2222')  two parameters : 22 2222
  • 70. Closure - Method Takes Closure  A method that takes a closure  class Name {  def first  def modify(Closure closure) {  closure.call this  }  String toString() {first}  }  def capitalizer = { Name name ->  name.first = name.first.capitalize()  }  def paul = new Name(name:"paul")  println "before = " + paul  paul.modify capitalizer  println "after = " + paul  before = paul  after = Paul
  • 71. Closure - Delegate  Delegate changes the scope of a closure  class Name {  def name = ""  }  def name1 = new Name(name:"Paul")  def name2 = new Name(name:"Woods")  def namePrinter = { ->  println name  }  namePrinter.delegate = name1  namePrinter()  namePrinter.delegate = name2  namePrinter()  Paul  Woods
  • 72. MultiAssign  Initialize or assign multiple variables with values from a list.  def a  def b  (a, b) = [ 1, 2 ]  def (c, d) = [ 3 , 4 ]  println "a=$a"  println "b=$b"  println "c=$c"  println "d=$d"  a=1  b=2  c=3  d=4
  • 73. Optional parenthesis, semicolons, and returns  In some situations, groovy allows you to remove parenthesis, semicolons and return statements.
  • 74. Optional - Parenthesis 1  No Arguments and no „get‟ prefix - () mandatory  class Name {  def first, last  def print() { println first + " " + last }  def printDelim(delim) { println first + delim + last }  def getFullName() { return first + " " + last }  def getTotal(delim) { return first + delim + last }  }  def name = new Name(first:"Paul", last:"Woods")  name.print() // () required  Paul Woods
  • 75. Optional - Parenthesis 2  One or more arguments and not referencing the return value - () optional  class Name {  def first, last  def print() { println first + " " + last }  def printDelim(delim) { println first + delim + last }  def getFullName() { return first + " " + last }  def getTotal(delim) { return first + delim + last }  }  def name = new Name(first:"Paul", last:"Woods")  name.printDelim " " // () not required  Paul Woods
  • 76. Optional - Parenthesis 3  The method has a „get‟ prefix, and no arguments. () optional  class Name {  def first, last  def print() { println first + " " + last }  def printDelim(delim) { println first + delim + last }  def getFullName() { return first + " " + last }  def getTotal(delim) { return first + delim + last }  }  def name = new Name(first:"Paul", last:"Woods")  println name.fullName // drop get prefix and ()  Paul Woods
  • 77. Optional - Parenthesis 4  Method has „get‟ prefix and 1 or more arguments and using the return value. () mandatory  class Name {  def first, last  def print() { println first + " " + last }  def printDelim(delim) { println first + delim + last }  def getFullName() { return first + " " + last }  def getTotal(delim) { return first + delim + last }  }  def name = new Name(first:"Paul", last:"Woods")  println name.getTotal(",") // () mandatory  Paul Woods
  • 78. Optional - Semicolons  Semicolons are almost always optional  Must be used if multiple statements on a single line.  def a = 1  def b = 2  println a  println b  println a; println b 1 2 1 2
  • 79. Optional - Returns - 1  Returns are optional when the value to be returned is the last line of the method.  def sum(a, b) {  a+b }  def sub(a, b) {  def total = a + b  total }
  • 80. Optional - Returns - 2  Returns are optional when the method is a if/else method. The value to be returned is the last line of each block, and the if/else is the bottom of the method.  def choose(a, b, c) {  if(a > 0) {  b  } else if(a < 0) {  c  } else {  0  }  }  println " 1 : " + choose( 1, 10, 20)  println "-1 : " + choose(-1, 10, 20)  println " 0 : " + choose( 0, 10, 20)  1 : 10  -1 : 20  0:0
  • 81. PowerAssert  Power Assert - in a failed assert statement, groovy shows you the values of the objects.  def map = [a: [b: [c: 2]]]  assert 3 == map.a.b.c  Assertion failed:  assert 3 == map.a.b.c  | | | | |  | | | | 2  | | | [c:2]  | | [b:[c:2]]  | [a:[b:[c:2]]]  false
  • 82. PowerAssert - Gotcha 1  PowerAssert Gotcha - If the difference is leading/trailing white space, the assert won't display a difference.  def a = "a"  def b = "arn"  assert a == b  Assertion failed:  assert a == b  | | |  a | a  false  It fails, but you can't tell why
  • 83. Meta Programming  Groovy can dynamically modify the code of classes at runtime
  • 84. MP - Add Method to Object  Adding a method to a object  String a = "a"  String b = "b"  a.metaClass.hashIt = { ->  "#" + delegate + "#" }  println a.hashIt()  println b.hashIt()  #a#  Caught: groovy.lang.MissingMethodException: No signature of method: java.lang.String.hashIt() …
  • 85. MP - Add Method to Class  Adding a method to a class  String a = "a"  String b = "b"  String.metaClass.hashIt = { ->  "#" + delegate + "#" }  println a.hashIt()  println b.hashIt()  #a#  #b#
  • 86. MP - Add Static Method to Class  Adding a method to a class  String a = "a"  String.metaClass.static.hashIt = { ->  "#" + delegate + "#" }  println a.hashIt()  println String.hashIt()  #a#  #class java.lang.String#
  • 87. Conclusion  Read the Groovy JDK to see what Groovy added to the java classes.  http://groovy.codehaus.org/groovy-jdk/  Read about the groovy transformation annotations  http://groovy.codehaus.org/gapi/index.html?groovy/transform/ToString.html  Try Grails - Groovy / Spring / Hibernate WebApp  http://grails.org/  Try Gradle - Groovy Build Automation  http://gradle.org/  Try Gaelyk - Groovy on Google AppServer  http://gaelyk.appspot.com/  Try Griffon - Groovy desktop java applications  http://griffon.codehaus.org/  Try Gpars - Concurrency with Groovy  http://gpars.codehaus.org/  Abstract Syntax Trees  http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations