Scripting – Effective, Efficient, Groovy Life
                       Mail: oldratlee@gmail.com
                         Blog: http://oldratlee.com




                                   2010-10-9          1
1.   接触新事物心态         1.   Groovy语法详解
2.   Groovy Show          现在有很多书可以看了
     代码小例子,吊你胃口      2.   程序员信仰、语言宗教
3.   Groovy Intro
     特性语法简析,带你入门
4.   动态语言的原则观念
5.   动态语言对我们原有观念
     的修正(动态要注意的问题)
6.   Groovy的资料



                              2010-10-9   2
2010-10-9   3
   类型
   强类型/弱类型
   动态类型/静态类型
   脚本编程语言
   编译器/解释器
   闭包
   FP




                2010-10-9   4
   Shell
   Python, Perl, Ruby
   JavaScript
   PHP
   AWK, SED




                         2010-10-9   5
   FUD
    Fear、Uncertain、Doubt
    不敢、不知、不信
   花释子莫效应
   语言宗教、程序员信仰




                           2010-10-9   6
   过于激进
   没有做足够的成本风险分析调查即采用




                        2010-10-9   7
要有一个好心态!

 什么是好心态?

  为什么说是好心
  态?
       即是说 标准是什么?我们要找到一把好尺子。
       一把照着做不会被颠覆,会和谐,会发展的尺子。




                        2010-10-9   8
2010-10-9   9
Groovy is like a super version of Java. It can
leverage Java's enterprise capabilities but also has
cool productivity features like closures, DSL support,
builders and dynamic typing.
 Groovy = Java       – boiler plate code
             +      optional dynamic typing
             +      closures
             +      domain specific languages
             +      builders
             +      meta programming




                                           2010-10-9     10
2010-10-9   11
2010-10-9   12
2010-10-9   13
2010-10-9   14
2010-10-9   15
2010-10-9   16
bike = new BikeGroovyBean(
    manufacturer:’中国东风’,
    model:‘X60’,
    serialNo:‘N80’,
    status:‘ready’,
    frame:200,
    weight:300,
    cost:3000000
)
              2010-10-9      17
def sql = groovy.sql.Sql.newInstance(
  "jdbc:mysql://localhost:3306/mydb", "user",
  "pswd", "com.mysql.jdbc.Driver")

sql.eachRow("select * from FOOD") {
  println "${it.name}"
}



# 上面不是代码片段,而真正可运行的代码




                                            2010-10-9   18
def xml = new groovy.xml.MarkupBuilder()

xml.person(id:99) {
  firstname("John")
  lastname("Smith")
}




上面代码的运行结果:
<person id='99'>
<firstname>John</firstname>
<lastname>Smith</lastname>
</person>


                                           2010-10-9   19
   减少Keyboard Type的本质和关键:
    尽量把软件的偶然复杂度中本质复杂度中去除
    # 参见《代码大全》《DDD》

   代码是代码是软件的根,代码的简化意味着所有软
    件活动的相应简化,这些都是成本。

   减少Type的能量,这样会减少CO2的排放。绿色环
    境。


                       2010-10-9   20
摘自《代码大全》
           摘自《人月神话》
           编程系统产品 对比 程序 的成本是9倍
           # 代码量的减少带来的成本减少 肯定被“9”放大
   对Groovy特性和语法简介
   和Java一致的语法略过

   这一节大家看到语法的疑惑时,随时可以问。




                     2010-10-9   22
   Automatic Imports
    ◦   import   java.lang.*;
    ◦   import   java.util.*;
    ◦   import   java.net.*;
    ◦   import   java.io.*;
    ◦   import   java.math.BigInteger;
    ◦   import   java.math.BigDecimal;
    ◦   import   groovy.lang.*;
    ◦   import   groovy.util.*;
   Optional Semicolons
   Optional Parentheses                    def metho1(x, y, closure1) {}
    ◦   println("Hello World!")
    ◦   println "Hello World!"              method1(x, y, { ...... })
   Optional Return Statements              method1(x, y) { ...... }
    ◦   String getFullName(){               method1 x, y, { ...... }
    ◦   return "${firstName} ${lastName}"
    ◦   }
    ◦   //equivalent code                   method1(x, y, clos)
    ◦   String getFullName(){               method1(x, y) clos // ERR
    ◦   "${firstName} ${lastName}"          method1 x, y, clos
    ◦   }

   Optional Datatype Declaration
   Optional Exception Handling

                                                          2010-10-9         23
Operator        Method
                                                          a + b           a.plus(b)
   Operator Overloading                                  a - b           a.minus(b)
                                                          a * b           a.multiply(b)
    ◦ Groovy支持的运算符                                        a ** b          a.power(b)
    ◦   http://groovy.codehaus.org/Operators              a / b           a.div(b)
    ◦   http://groovy.codehaus.org/Operator+Overloading   a % b           a.mod(b)
                                                          a | b           a.or(b)
    ◦   例子:                                               a & b           a.and(b)
    ◦   10 ** 3 = 1000                                    a ^ b           a.xor(b)
    ◦   ~”.*http.*” (把一个String换成一个Pattern)                a++ or ++a      a.next()
                                                          a-- or --a      a.previous()
                                                          a[b]            a.getAt(b)
                                                          a[b] = c        a.putAt(b, c)
                                                          a << b          a.leftShift(b)
                                                          a >> b          a.rightShift(b)
                                                          switch(a){ case(b): }     b.isCase(a)
                                                          ~a    a.bitwiseNegate()
                                                          -a    a.negative()
   Safe Dereferencing                                    +a    a.positive()
    ◦   s?.size()                                         a == b          a.equals(b) or
    ◦   ===> null                                                         a.compareTo(b) == 0 **
                                                          a != b          ! a.equals(b)
   Autoboxing                                            a <=> b         a.compareTo(b)
                                                          a > b           a.compareTo(b) > 0
                                                          a >= b          a.compareTo(b) >= 0
                                                          a < b           a.compareTo(b) < 0
                                                          a <= b          a.compareTo(b) <= 0

                                                                              2010-10-9            24
   5/3 = 1.66666667
   5.intdiv(3) = 1


   类型后缀
   G   java.math.BigInteger   55G
   L   java.lang.Long         55L
   I   java.lang.Integer      55I
   G   java.math.BigDecimal   3.14G
   D   java.lang.Double       3.14D
   F   java.lang.Float        3.14F




                                       2010-10-9   25
class X
{
    def field

    def getField()
    {
        field += 1
    }
}

x = new   X()
x.field   = 1
println   x.@field   // 1
println   x.field    // 2




                            2010-10-9   26
lst = [1, 2, 3]
assert [*lst, 4, 5] == [1, 2, 3, 4, 5]
methodFoo(*lst)   // 方法调用参数也一样



assert ['cat', 'elephant']*.size() == [3, 8]

parent*.action                             //equivalent to:
parent.collect{ child -> child?.action }




class1*.@field1

m1 = [key1:1, key2:2]
m2 = [*:m1, key3:3] // map的展开
====> [key1=1, key2=2, key3=3]




                                                         2010-10-9   27
m2 = System.&clearProperty // 静态方法
===> org.codehaus.groovy.runtime.MethodClosure@4c61a7e6

m2(“foo”)




class X {
   def doSomething() { println "hello" }
}
def obj = new X()
def methRef = obj.&doSomething // 成员方法
methRef()




                                                          2010-10-9   28
def matcher = "cheesecheese" =~ /cheese/
assert matcher instanceof Matcher

def m = "foobarfoo" =~ /o(b.*r)f/
assert m[0] == ["obarf", "bar"]
assert m[0][1] == "bar"



assert "2009" ==~ /d+/   // returns TRUE
assert "holla" ==~ /d+/ // returns FALSE
assert "holla" ==~ ~/d+/ // returns FALSE




                                             2010-10-9   29
代码例子

                               // In Java
                               if(args != null && args.length > 0){
                               File dir = new File(args[0]);
                               }
                               else{
                               System.out.println("Usage: ListDir /some/dir/name");
                               }


Groovy 1.7 能自定义Groovy Truth。   //in Groovy:
改写Object的asBoolean()方法         if(args){
                               dir = new File(args[0])
                               }
                               else{
                               println "Usage: ListDir /some/dir/name"
                               }

                                                         2010-10-9            30
   使用单引号
    ◦   „Hello  “‟            Hello  ”
    ◦   „Hello “W” $name‟        Hello “W” $name

   使用双引号
    ◦   “Hello  „”             Hello  „
    ◦   “Hello „W‟ $name”        Hello „w‟ jerry

   使用三个引号
    ◦   „‟‟Hello  „W‟ “W”
    ◦   $name‟‟‟                      Hello  „W‟ “W”n$name

    ◦   “”” Hello  „W‟ “W”
    ◦   $name”””                      Hello  „W‟ “W”njerry

   使用/
    ◦   /Hello”‟ d / $name/           Hello”‟ d / jerry




                                                               2010-10-9   31
def languages = ["Java", "Groovy", "JRuby"]   groovy> languages.join(",")
println languages.class                       ===> Java,Groovy,JRuby
===> java.util.ArrayList                      def others = ["Jython", "JavaScript"]
                                              languages += others
def empty = []                                ===> [Java, Groovy, JRuby, Jython, JavaScript]
println empty.size()                          languages -= others
===> 0                                        ===> [Java, Groovy, JRuby]


def languages = ["Java", "Groovy", "JRuby"]   languages.sort()
languages << "Jython"                         languages.reverse()
===> [Java, Groovy, JRuby, Jython]            languages.pop()
def languages = ["Java", "Groovy", "JRuby"]
languages << "Jython"
===> [Java, Groovy, JRuby, Jython]
languages.each{println it}
===>
Java
Groovy
Jruby




                                                                    2010-10-9           32
def family = [dad:"John", 'mom':"Jane"]
println family.getClass()
===> java.util.LinkedHashMap


def empty = [:]
println empty.size()
===> 0


def family = [dad:"John", mom:"Jane"]
family.get("dad")
family.dad
===> John


def family = [dad:"John", mom:"Jane"]
family.put("kid", "Timmy")
family.kid2 = "Susie"
===> {dad=John, mom=Jane, kid=Timmy, kid2=Susie}




                                                   2010-10-9   33
def r = 1..3
println r.class
===> groovy.lang.IntRange
r.each{println it}
===>
1
2
3


def r = 1 ..< 4
===> 1, 2, 3


def today = new Date()
===> Sat Dec 29 23:59:28 MST 2007
def nextWeek = today + 2
===> Sat Jan 05 23:59:28 MST 2008
(today..nextWeek).each{println it}
===>
Sat Dec 29 23:59:28 MST 2007
Sun Dec 30 23:59:28 MST 2007
Mon Dec 31 23:59:28 MST 2007

                                     2010-10-9   34
def x = 1.23

switch ( x ) {
    case "foo“:
        println “String foo”
    case ~/d+/:
        println “String numbers”
    case [4, 5, 6, 'inList']:
        println “In List”
    case 12..30:
        println “In Range”
    case Integer:                  在Groovy中,类名表示class对象,即
        println “A Integer”        Integer == Integer.class
    default:
        println “Oops!”
}




                                                     2010-10-9   35
def hi = { println "Hi"}
hi()
===> Hi


def calculateTax = { taxRate, amount ->
return amount + (taxRate * amount)
}
println "Total cost: ${calculateTax(0.055, 100)}"
===> Total cost: 105.500



def tax = calculateTax.curry(0.1)
[10,20,30].each{
println "Total cost: ${tax(it)}"
}
===>
Total cost: 11.0
Total cost: 22.0
Total cost: 33.0




                                                    2010-10-9   36
how simple, elegant, and flexible your code is when you take advantage of
   dynamic typing? But, is this risky business?
• You might mistype the method name when creating one of the helpers.
• Without the type information, how do you know what to send to your
   method?
• What if you send a object(which haven’t the methods) to the method?




Programming with dynamic typing without having the discipline of unit
  testing is playing with wildfire.




                                                          2010-10-9        37
2010-10-9   38
http://groovy.codehaus.org/
Groovy的官方网站
有超过1000面的资料,入门的、深入的。

http://groovy.codehaus.org/groovy-jdk/
官方文档,Groovy对JDK的扩展,一般叫GDK

http://groovy.codehaus.org/gapi/
Groovy的API文档


                                   2010-10-9   39
《Groovy Programming, An Introduction for jdk Developers》,2007出版
有中文版:《Groovy入门经典》
经典的Groovy入门书籍,而且应该是最早出版的Groovy书籍,拿来做教材不错。
虽然用的老版本的Groovy,但是有最基础的内容,在后面的几本书中都没有去讲。

《Groovy in Action》,2007年出版,使用的是Groovy 1.0-RC-01
Groovy实战,早就听说要有中文版出版,但到现在还不见影子。
一本入门和进阶的书籍,非常不错,就是有点厚(内容充实嘛)。

《Groovy Recipes, Greasing the Wheels of jdk》 2008,使用的是Groovy 1.5.0 ,Groovy
 秘笈,属于Groovy进阶读物了,里面关于Parsing XML 和 Writing XML两章写得相当
 不错

《Programming Groovy, Dynamic Productivity for the jdk Developer》 2008,使用的是
 Groovy 1.5.4,也是进阶读物,强烈推荐读这本。
特别是关于第三部MOPping Groovy,唯一一本详细介绍Groovy元编程的书籍,
 Groovy秘笈只是简单的介绍,而Programming Groovy则非常详细、且通俗易懂。




                                                           2010-10-9         40
《Beginning.Groovy.and.Grails.From.Novice.to.Professional》
 2008,使用的是Groovy 1.5.6、grails-1.0,Groovy和Grails由入
 门到精通
《The.Definitive.Guide.to.Grails》 2009年出了第二版
中文版:Grails权威指南
Guillaume Laforge亲自操刀写的书,难道你能错过吗?
中文版去年就电子工业出版社出版。
《Grails in Action》 2009,使用的是Grails 1.1
《Grails, A Quick-Start Guide》 2009,使用的是Grails 1.1.1
《Getting Started with Grails》 中文版:Grails入门指南
我的评价 Grails入门指南,薄且通俗易懂

PS:
可以看到2009出了很多本Grails的书,从一个方面说明了
  Groovy的被更广泛的关注和使用。
                                            2010-10-9       41
《 Grails Persistence with GORM and GSQL》 2009,只
 有150面。

《 Scripting in jdk:Languages,Frameworks,and Patterns 》
 2007
中文版:Java脚本编程:语言、框架与模式
这本书有比较深入的讨论,在其它书中没有。
对Scriptin API的介绍,会大大加强的你对Scripting能
 力的认识,开阔你的视野。
这本书有一部分是对Groovy的介绍,也写的不错。

                                         2010-10-9       42

Groovy Introduction for Java Programmer

  • 1.
    Scripting – Effective,Efficient, Groovy Life Mail: oldratlee@gmail.com Blog: http://oldratlee.com 2010-10-9 1
  • 2.
    1. 接触新事物心态 1. Groovy语法详解 2. Groovy Show 现在有很多书可以看了 代码小例子,吊你胃口 2. 程序员信仰、语言宗教 3. Groovy Intro 特性语法简析,带你入门 4. 动态语言的原则观念 5. 动态语言对我们原有观念 的修正(动态要注意的问题) 6. Groovy的资料 2010-10-9 2
  • 3.
  • 4.
    类型  强类型/弱类型  动态类型/静态类型  脚本编程语言  编译器/解释器  闭包  FP 2010-10-9 4
  • 5.
    Shell  Python, Perl, Ruby  JavaScript  PHP  AWK, SED 2010-10-9 5
  • 6.
    FUD Fear、Uncertain、Doubt 不敢、不知、不信  花释子莫效应  语言宗教、程序员信仰 2010-10-9 6
  • 7.
    过于激进  没有做足够的成本风险分析调查即采用 2010-10-9 7
  • 8.
    要有一个好心态! 什么是好心态? 为什么说是好心 态? 即是说 标准是什么?我们要找到一把好尺子。 一把照着做不会被颠覆,会和谐,会发展的尺子。 2010-10-9 8
  • 9.
  • 10.
    Groovy is likea super version of Java. It can leverage Java's enterprise capabilities but also has cool productivity features like closures, DSL support, builders and dynamic typing. Groovy = Java – boiler plate code + optional dynamic typing + closures + domain specific languages + builders + meta programming 2010-10-9 10
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
    bike = newBikeGroovyBean( manufacturer:’中国东风’, model:‘X60’, serialNo:‘N80’, status:‘ready’, frame:200, weight:300, cost:3000000 ) 2010-10-9 17
  • 18.
    def sql =groovy.sql.Sql.newInstance( "jdbc:mysql://localhost:3306/mydb", "user", "pswd", "com.mysql.jdbc.Driver") sql.eachRow("select * from FOOD") { println "${it.name}" } # 上面不是代码片段,而真正可运行的代码 2010-10-9 18
  • 19.
    def xml =new groovy.xml.MarkupBuilder() xml.person(id:99) { firstname("John") lastname("Smith") } 上面代码的运行结果: <person id='99'> <firstname>John</firstname> <lastname>Smith</lastname> </person> 2010-10-9 19
  • 20.
    减少Keyboard Type的本质和关键: 尽量把软件的偶然复杂度中本质复杂度中去除 # 参见《代码大全》《DDD》  代码是代码是软件的根,代码的简化意味着所有软 件活动的相应简化,这些都是成本。  减少Type的能量,这样会减少CO2的排放。绿色环 境。 2010-10-9 20
  • 21.
    摘自《代码大全》 摘自《人月神话》 编程系统产品 对比 程序 的成本是9倍 # 代码量的减少带来的成本减少 肯定被“9”放大
  • 22.
    对Groovy特性和语法简介  和Java一致的语法略过  这一节大家看到语法的疑惑时,随时可以问。 2010-10-9 22
  • 23.
    Automatic Imports ◦ import java.lang.*; ◦ import java.util.*; ◦ import java.net.*; ◦ import java.io.*; ◦ import java.math.BigInteger; ◦ import java.math.BigDecimal; ◦ import groovy.lang.*; ◦ import groovy.util.*;  Optional Semicolons  Optional Parentheses def metho1(x, y, closure1) {} ◦ println("Hello World!") ◦ println "Hello World!" method1(x, y, { ...... })  Optional Return Statements method1(x, y) { ...... } ◦ String getFullName(){ method1 x, y, { ...... } ◦ return "${firstName} ${lastName}" ◦ } ◦ //equivalent code method1(x, y, clos) ◦ String getFullName(){ method1(x, y) clos // ERR ◦ "${firstName} ${lastName}" method1 x, y, clos ◦ }  Optional Datatype Declaration  Optional Exception Handling 2010-10-9 23
  • 24.
    Operator Method a + b a.plus(b)  Operator Overloading a - b a.minus(b) a * b a.multiply(b) ◦ Groovy支持的运算符 a ** b a.power(b) ◦ http://groovy.codehaus.org/Operators a / b a.div(b) ◦ http://groovy.codehaus.org/Operator+Overloading a % b a.mod(b) a | b a.or(b) ◦ 例子: a & b a.and(b) ◦ 10 ** 3 = 1000 a ^ b a.xor(b) ◦ ~”.*http.*” (把一个String换成一个Pattern) a++ or ++a a.next() a-- or --a a.previous() a[b] a.getAt(b) a[b] = c a.putAt(b, c) a << b a.leftShift(b) a >> b a.rightShift(b) switch(a){ case(b): } b.isCase(a) ~a a.bitwiseNegate() -a a.negative()  Safe Dereferencing +a a.positive() ◦ s?.size() a == b a.equals(b) or ◦ ===> null a.compareTo(b) == 0 ** a != b ! a.equals(b)  Autoboxing a <=> b a.compareTo(b) a > b a.compareTo(b) > 0 a >= b a.compareTo(b) >= 0 a < b a.compareTo(b) < 0 a <= b a.compareTo(b) <= 0 2010-10-9 24
  • 25.
    5/3 = 1.66666667  5.intdiv(3) = 1  类型后缀  G java.math.BigInteger 55G  L java.lang.Long 55L  I java.lang.Integer 55I  G java.math.BigDecimal 3.14G  D java.lang.Double 3.14D  F java.lang.Float 3.14F 2010-10-9 25
  • 26.
    class X { def field def getField() { field += 1 } } x = new X() x.field = 1 println x.@field // 1 println x.field // 2 2010-10-9 26
  • 27.
    lst = [1,2, 3] assert [*lst, 4, 5] == [1, 2, 3, 4, 5] methodFoo(*lst) // 方法调用参数也一样 assert ['cat', 'elephant']*.size() == [3, 8] parent*.action //equivalent to: parent.collect{ child -> child?.action } class1*.@field1 m1 = [key1:1, key2:2] m2 = [*:m1, key3:3] // map的展开 ====> [key1=1, key2=2, key3=3] 2010-10-9 27
  • 28.
    m2 = System.&clearProperty// 静态方法 ===> org.codehaus.groovy.runtime.MethodClosure@4c61a7e6 m2(“foo”) class X { def doSomething() { println "hello" } } def obj = new X() def methRef = obj.&doSomething // 成员方法 methRef() 2010-10-9 28
  • 29.
    def matcher ="cheesecheese" =~ /cheese/ assert matcher instanceof Matcher def m = "foobarfoo" =~ /o(b.*r)f/ assert m[0] == ["obarf", "bar"] assert m[0][1] == "bar" assert "2009" ==~ /d+/ // returns TRUE assert "holla" ==~ /d+/ // returns FALSE assert "holla" ==~ ~/d+/ // returns FALSE 2010-10-9 29
  • 30.
    代码例子 // In Java if(args != null && args.length > 0){ File dir = new File(args[0]); } else{ System.out.println("Usage: ListDir /some/dir/name"); } Groovy 1.7 能自定义Groovy Truth。 //in Groovy: 改写Object的asBoolean()方法 if(args){ dir = new File(args[0]) } else{ println "Usage: ListDir /some/dir/name" } 2010-10-9 30
  • 31.
    使用单引号 ◦ „Hello “‟ Hello ” ◦ „Hello “W” $name‟ Hello “W” $name  使用双引号 ◦ “Hello „” Hello „ ◦ “Hello „W‟ $name” Hello „w‟ jerry  使用三个引号 ◦ „‟‟Hello „W‟ “W” ◦ $name‟‟‟ Hello „W‟ “W”n$name ◦ “”” Hello „W‟ “W” ◦ $name””” Hello „W‟ “W”njerry  使用/ ◦ /Hello”‟ d / $name/ Hello”‟ d / jerry 2010-10-9 31
  • 32.
    def languages =["Java", "Groovy", "JRuby"] groovy> languages.join(",") println languages.class ===> Java,Groovy,JRuby ===> java.util.ArrayList def others = ["Jython", "JavaScript"] languages += others def empty = [] ===> [Java, Groovy, JRuby, Jython, JavaScript] println empty.size() languages -= others ===> 0 ===> [Java, Groovy, JRuby] def languages = ["Java", "Groovy", "JRuby"] languages.sort() languages << "Jython" languages.reverse() ===> [Java, Groovy, JRuby, Jython] languages.pop() def languages = ["Java", "Groovy", "JRuby"] languages << "Jython" ===> [Java, Groovy, JRuby, Jython] languages.each{println it} ===> Java Groovy Jruby 2010-10-9 32
  • 33.
    def family =[dad:"John", 'mom':"Jane"] println family.getClass() ===> java.util.LinkedHashMap def empty = [:] println empty.size() ===> 0 def family = [dad:"John", mom:"Jane"] family.get("dad") family.dad ===> John def family = [dad:"John", mom:"Jane"] family.put("kid", "Timmy") family.kid2 = "Susie" ===> {dad=John, mom=Jane, kid=Timmy, kid2=Susie} 2010-10-9 33
  • 34.
    def r =1..3 println r.class ===> groovy.lang.IntRange r.each{println it} ===> 1 2 3 def r = 1 ..< 4 ===> 1, 2, 3 def today = new Date() ===> Sat Dec 29 23:59:28 MST 2007 def nextWeek = today + 2 ===> Sat Jan 05 23:59:28 MST 2008 (today..nextWeek).each{println it} ===> Sat Dec 29 23:59:28 MST 2007 Sun Dec 30 23:59:28 MST 2007 Mon Dec 31 23:59:28 MST 2007 2010-10-9 34
  • 35.
    def x =1.23 switch ( x ) { case "foo“: println “String foo” case ~/d+/: println “String numbers” case [4, 5, 6, 'inList']: println “In List” case 12..30: println “In Range” case Integer: 在Groovy中,类名表示class对象,即 println “A Integer” Integer == Integer.class default: println “Oops!” } 2010-10-9 35
  • 36.
    def hi ={ println "Hi"} hi() ===> Hi def calculateTax = { taxRate, amount -> return amount + (taxRate * amount) } println "Total cost: ${calculateTax(0.055, 100)}" ===> Total cost: 105.500 def tax = calculateTax.curry(0.1) [10,20,30].each{ println "Total cost: ${tax(it)}" } ===> Total cost: 11.0 Total cost: 22.0 Total cost: 33.0 2010-10-9 36
  • 37.
    how simple, elegant,and flexible your code is when you take advantage of dynamic typing? But, is this risky business? • You might mistype the method name when creating one of the helpers. • Without the type information, how do you know what to send to your method? • What if you send a object(which haven’t the methods) to the method? Programming with dynamic typing without having the discipline of unit testing is playing with wildfire. 2010-10-9 37
  • 38.
  • 39.
  • 40.
    《Groovy Programming, AnIntroduction for jdk Developers》,2007出版 有中文版:《Groovy入门经典》 经典的Groovy入门书籍,而且应该是最早出版的Groovy书籍,拿来做教材不错。 虽然用的老版本的Groovy,但是有最基础的内容,在后面的几本书中都没有去讲。 《Groovy in Action》,2007年出版,使用的是Groovy 1.0-RC-01 Groovy实战,早就听说要有中文版出版,但到现在还不见影子。 一本入门和进阶的书籍,非常不错,就是有点厚(内容充实嘛)。 《Groovy Recipes, Greasing the Wheels of jdk》 2008,使用的是Groovy 1.5.0 ,Groovy 秘笈,属于Groovy进阶读物了,里面关于Parsing XML 和 Writing XML两章写得相当 不错 《Programming Groovy, Dynamic Productivity for the jdk Developer》 2008,使用的是 Groovy 1.5.4,也是进阶读物,强烈推荐读这本。 特别是关于第三部MOPping Groovy,唯一一本详细介绍Groovy元编程的书籍, Groovy秘笈只是简单的介绍,而Programming Groovy则非常详细、且通俗易懂。 2010-10-9 40
  • 41.
    《Beginning.Groovy.and.Grails.From.Novice.to.Professional》 2008,使用的是Groovy 1.5.6、grails-1.0,Groovy和Grails由入 门到精通 《The.Definitive.Guide.to.Grails》 2009年出了第二版 中文版:Grails权威指南 Guillaume Laforge亲自操刀写的书,难道你能错过吗? 中文版去年就电子工业出版社出版。 《Grails in Action》 2009,使用的是Grails 1.1 《Grails, A Quick-Start Guide》 2009,使用的是Grails 1.1.1 《Getting Started with Grails》 中文版:Grails入门指南 我的评价 Grails入门指南,薄且通俗易懂 PS: 可以看到2009出了很多本Grails的书,从一个方面说明了 Groovy的被更广泛的关注和使用。 2010-10-9 41
  • 42.
    《 Grails Persistencewith GORM and GSQL》 2009,只 有150面。 《 Scripting in jdk:Languages,Frameworks,and Patterns 》 2007 中文版:Java脚本编程:语言、框架与模式 这本书有比较深入的讨论,在其它书中没有。 对Scriptin API的介绍,会大大加强的你对Scripting能 力的认识,开阔你的视野。 这本书有一部分是对Groovy的介绍,也写的不错。 2010-10-9 42