Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Java開発の強力な相棒として今すぐ使えるGroovy

 Java開発の強力な相棒として今すぐ使えるGroovy

Presentation slide of my session of Groovy at JJUG CCC 2015 Spring

Yasuharu Nakano

March 25, 2023
Tweet

More Decks by Yasuharu Nakano

Other Decks in Programming

Transcript

  1. JO+BWB //  HelloWorld.java   public  class  HelloWorld  {    

         public  static  void  main(String...  args)  {                  System.out.println("Hello,  World!");          }   }   //=>  Hello,  World!
  2. JO(SPPWZ //  HelloWorld.groovy   public  class  HelloWorld  {    

         public  static  void  main(String...  args)  {                  System.out.println("Hello,  World!");          }   }   //=>  Hello,  World! Groovyͱͯ͠΋validͳίʔυͳͷͰ ֦ுࢠΛม͑Δ͚ͩͰOK
  3. JO(SPPWZ //  HelloWorld.groovy   public  class  HelloWorld  {    

         public  static  void  main(String...  args)  {                  System.out.println("Hello,  World!");          }   }   //=>  Hello,  World! ηϛίϩϯ͸লུՄೳ
  4. JO(SPPWZ //  HelloWorld.groovy   public  class  HelloWorld  {    

         public  static  void  main(String...  args)  {                  System.out.println("Hello,  World!")          }   }   //=>  Hello,  World! Object#println()͕࢖͑ΔʢGDKͷͻͱͭʣ
  5. JO(SPPWZ //  HelloWorld.groovy   public  class  HelloWorld  {    

         public  static  void  main(String...  args)  {                  println("Hello,  World!")          }   }   //=>  Hello,  World! εΫϦϓτܗࣜͰ࣮ߦՄೳʢΫϥε͕ෆཁʣ
  6. ಈతܕ෇͚ͷྫ Integer  num  =  "Hello"   //=>  GroovyCastException:  Cannot  cast

     object  'Hello'   with  class  'java.lang.String'  to  class   'java.lang.Integer' groovycͰίϯύΠϧʹ͸੒ޭ͢Δ ͔͠͠ɺ࣮ߦ͢Δͱྫ֎͕ൃੜ͢Δ
  7. ηϛίϩϯ͸লུՄೳ //  ηϛίϩϯ͸ෆཁ   int  a  =  1   //

     ηϛίϩϯ͸͋ͬͯ΋OK͕ͩɺ෇͚ͳ͍ํ͕͓קΊ   int  b  =  2;
  8. SFUVSO΋লུՄೳ String  hello()  {          //  return͸লུͰ͖Δ

             //  Ruby౳ͱಉ༷ʹ࠷ޙʹධՁ͞Εͨ஋͕ฦΔ      "Hello"   }   assert  hello()  ==  "Hello"
  9. νΣοΫྫ֎ͷUISPXTએݴ΋লུՄೳ String  doWithoutThrows()  {          throw  new

     Exception("νΣοΫྫ֎ʂ")   }   try  {          doWithoutThrows()          assert  false   }  catch  (Exception  e)  {          assert  e.getMessage()  ==  "νΣοΫྫ֎ʂ"   } throws͕ͳͯ͘΋OKʂ
  10. ܕએݴ΋লུՄೳ def  Ωʔϫʔυ 0CKFDUܕͷผ໊ͱͯ͠એݴ࣌ʹ࢖͑Δ
 
 ҎԼͷ৔߹ɺܕએݴࣗମΛলུՄೳʢˠ0CKFDUܕʣ ϝιου΍ม਺ͰɺQSJWBUF΍TUBUJDͳͲͷम০ࢠ͕ͭҎ্͋Δ৔߹ ϝιουͷԾҾ਺ final  helloPrefix

     =  "Hello,  "   public  hello(name)  {        def  message  =  helloPrefix  +  name        return  message   } লུ͸Ͱ͖Δ͕ɺυΩϡϝϯςʔγϣϯͱͯ͠ߟ͑Δͱɺެ։"1*ͷγάωνϟͰ ͸ܕΛ໌ه͢Δํ͕޷·͍͠ def  hoge  =  "΄͛"
  11. ϓϦϛςΟϒܕͰએݴͯ͠΋࣮ମ͸ϥούʔܕ ͨͩ͠ɺOVMM͸୅ೖෆՄೳ ·ͨɺ࠷దԽػߏʹΑΓɺՄೳͳ৔߹ʹ͓͍ͯ಺෦తʹ ΋ϓϦϛςΟϒܕͷ··ѻΘΕΔ৔߹΋͋Δ ϓϦϛςΟϒܕ͸ϥούʔܕ assert  1.getClass()  ==  java.lang.Integer  

    double  d  =  1.0   assert  d.getClass()  ==  java.lang.Double   assert  true.getClass()  ==  java.lang.Boolean   //  ΋ͪΖΜϝιου΋ݺ΂Δ   assert  d.plus(2.5)  ==  3.5   //  null͸୅ೖෆՄೳ   d  =  null  //=>  GroovyCastException:  Cannot  cast  object  'null'   with  class  'null'  to  class  'double'.
  12. Ϧςϥϧɿ਺஋ (SPPWZͷුಈখ਺Ϧςϥϧ͸#JH%FDJNBMܕ ܻ͋;Ε΍ޡࠩΛؾʹ͠ͳ͍ͰԋࢉͰ͖Δ ϓϦϛςΟϒܕͷΑ͏ʹ௨ৗͷதஔԋࢉࢠ͕࢖͑Δ assert  5.3.getClass()  ==  java.math.BigDecimal   //

     ී௨ʹதஔԋࢉࢠ΋࢖͑Δ   assert  (1.0  /  3)  ==  0.3333333333   assert  (1.0  /  3).getClass()  ==  java.math.BigDecimal   //  JavaͰ͸ޡ͕ࠩൃੜ͢Δ͕ɺGroovy͸BigDecimalͳͷͰҰக͢Δ   assert  (1.0  -­‐  (1.0  /  3.0))  ==  (2.0  /  3.0) #ccc_cd3 ͰBigDecimal࿩͕͋Γ·ͨ͠Ͷ
  13. Ϧςϥϧɿจࣈྻ //  جຊ͸Javaͱಉ͘͡μϒϧΫΥʔςʔγϣϯ   println  "Hello,  World!"    //=>  Hello,

     World!   //  ${}ʹΑͬͯม਺Λల։Ͱ͖ΔʢฆΒΘ͘͠ͳ͚Ε͹{}΋লུͰ͖Δʣ   String  name  =  "World"   assert  "Hello,  ${name}!"  ==  "Hello,  World!"   //  ݫີʹ͸GStringܕͷϦςϥϧ   assert  "Hello,  ${name}!".getClass()  ==   org.codehaus.groovy.runtime.GStringImpl   //  ७ਮʹStringܕ͕ඞཁͳ৔߹͸γϯάϧΫΥʔςʔγϣϯΛ࢖͏   //  JavaͰ͸charܕϦςϥϧ͕ͩͬͨɺGroovyͰ͸charܕϦςϥϧ͸ແ͠   assert  'Hello,  ${name}!'  !=  "Hello,  World!"
  14. Ϧςϥϧɿจࣈྻ //  τϦϓϧʮμϒϧΫΥʔτʯʢ΍΍͍͜͠ʣ   //  վߦ΍୯ମͷΫΥʔτจࣈྻࣗମΛؚΊΒΕΔʢGStringܕʣ   //  τϦϓϧʮγϯάϧΫΥʔτʯʹ͢Δͱ୯ͳΔStringܕʹͳΔʢల։ແ͠ʣ  

    def  s  =  "Third"   println  """First,   "Second",   ${s}.   """   //=>   //  First,   //  "Second",   //  Third. ώΞυΩϡϝϯτ෩ʹ࢖͑Δ
  15. Ϧςϥϧɿจࣈྻ //  ։࢝ߦͷߦ຤ΤεέʔϓͱString#stripMargin()Λ࢖͏ͱɺ   //  ͍͍ײ͡ʹΠϯσϯτͰ͖ͯɺಡΈ΍͍͢   def  s  =

     "Third"   println  """\          |First,          |"Second",          |${s}.          |""".stripMargin()   //=>   //  First,   //  "Second",   //  Third. GDKͷString#stripMargin()ͱ߹Θͤͯ࢖ ͏ͱΠϯσϯτ΋͍͍ײ͡ʹͰ͖Δ
  16. Ϧςϥϧɿจࣈྻ //  εϥογϡΫΥʔτ   //  ୯ମόοΫεϥογϡΛಛघจࣈͱͯ͠ѻΘͳ͍ͨΊɺΤεέʔϓ͕ෆཁɻ   //  ਖ਼نදݱΛγϯϓϧʹॻ͚Δ  

    assert  (/This  is  backslash  '\n'/  ==  "This  is  backslash  '\\n'")   assert  "Hello,  World!".matches(/Hello,\s.*/)   //  PatternܕͰ͸ͳ͘ɺ͋͘·ͰStringܕ   assert  (/Not  Pattern,  But  String/.getClass()  ==  String)   //  ؙׅހͰғ·ͳ͍ͱίϯύΠϧΤϥʔʹͳΔέʔε͕͋ΔͷͰ஫ҙ   assert  /Naked  Slashed/          //=>  "1  compilation  error:  unexpected  token:  /" ਖ਼نදݱΛॻ͘ͱ͖͸அવίϨ
  17. ϦςϥϧɿϦετ //  ઐ༻ϦςϥϧͷಋೖʹΑΓɺγϯϓϧʹϦετΛهड़Ͱ͖Δ   def  l  =  [1,  2,  3,

     4,  5]   assert  l.size()  ==  5   assert  l.getClass()  ==  java.util.ArrayList   //  ۭϦετ   assert  [].size()  ==  0   //  ཁૉ΁ͷΞΫηε   assert  l[0]  ==  1   assert  l[2..3]  ==  [3,  4]   assert  l.first()  ==  1   assert  l.last()  ==  5   assert  l.head()  ==  1   assert  l.tail()  ==  [2,  3,  4,  5]
  18. ʢࢀߟʣϦςϥϧɿηοτ //  ηοτઐ༻ͷϦςϥϧ͸ͳ͍͕ɺasʹΑΔܕม׵ͰදݱͰ͖Δ   def  s  =  [1,  2,  3,

     4,  5]  as  Set   assert  s.size()  ==  5   assert  s.getClass()  ==  java.util.LinkedHashSet  
  19. ϦςϥϧɿϚοϓ //  ઐ༻ϦςϥϧͷಋೖʹΑΓɺγϯϓϧʹϚοϓΛهड़Ͱ͖Δ   def  m  =  ['a':  1,  'b':

     2,  'c':  3]   assert  m.size()  ==  3   assert  m.getClass()  ==  java.util.LinkedHashMap   //  ۭϚοϓ   assert  [:].size()  ==  0   //  ΩʔʹจࣈྻΛࢦఆ͢Δ৔߹͸ΫΥʔτΛলུͰ͖Δ   assert  m  ==  [a:  1,  b:  2,  c:  3]   //  ཁૉ΁ͷΞΫηε   assert  m['a']  ==  1    //  ࿈૝഑ྻ෩   assert  m.a  ==  1          //  ϓϩύςΟΞΫηε෩
  20. ϝιουݺͼग़͠ def  hello()  {          "Hello!"  

    }   //  StringͰϝιου໊ΛࢦఆͰ͖Δ   assert  "hello"()  ==  "Hello!"   //  GStringΛ࢖ͬͯ΋OK   def  methodName  =  "hello"   assert  "$methodName"()  ==  "Hello!"
  21. ϝιουݺͼग़͠ //  ໊લ෇͖Ҿ਺ʁ   def  hello(Map  map)  {    

         "Hello,  ${map.name}${map.period}"   }   assert  hello(period:  "!",  name:  "World")  ==  "Hello,  World!"   //  ͜Εͷ[]ΛলུͰ͖ΔΠϝʔδ   assert  hello([period:  "!",  name:  "World"])  ==  "Hello,  World!"
  22. ϝιουݺͼग़͠ //  Ҿ਺ͷσϑΥϧτ஋   def  bye(name  =  "World")  {  

           "Good-­‐bye,  ${name}."   }   assert  bye()  ==  "Good-­‐bye,  World."   assert  bye("Yesterday")  ==  "Good-­‐bye,  Yesterday."
  23. ίϯετϥΫλݺͼग़͠ class  Sample  {          String  a

             String  b          int  c   }   //  Ҿ਺Λड͚औΔίϯετϥΫλΛࣗલͰॻ͍͍ͯͳ͚Ε͹ɺ   //  ύϥϝʔλ෇͖Ҿ਺ΛࢦఆͰ͖ΔศརͳίϯετϥΫλ͕ࣗಈੜ੒͞ΕΔ   def  sample  =  new  Sample(a:  "A",  c:  3,  b:  "B")   println  sample.dump()  //  σόοά࣌ʹศརͳGDK:  Object#dump()          //  =>  <Sample@3909c9e9  a=A  b=B  c=3>
  24. Ϋϩʔδϟ ଞݴޠͷୈڃؔ਺ΦϒδΣΫτ΍Ϋϩʔδϟͱಉ౳ +BWB4DSJQU 3VCZ 1FSM -JTQ  ୈҰڃΦϒδΣΫτͱͯ͠ɺม਺ʹ୅ೖͨ͠ΓҾ਺ ʹ౉ͨ͠ΓͰ͖Δ ߴ֊ؔ਺

    ແ໊಺෦Ϋϥε΍+BWBͷϥϜμه๏ΑΓ΋࣍ͷ఺ Ͱڧྗ ΫϩʔδϟΛએݴͨ͠จ๏্ͷείʔϓʢϨΩγΧϧε ίʔϓʣʹ͋Δม਺ʢϩʔΧϧม਺ΛؚΉʣΛࢀরɾม ߋͰ͖Δ
  25. Ϋϩʔδϟɿఆٛͱ࣮ߦ //  ΫϩʔδϟΛఆٛ͢Δ   Closure  c  =  {    

         return  "Hello,  Closure!"   }   //  ࣮ߦ͢Δ   assert  c.call()  ==  "Hello,  Closure!"   //  callΛলུ͢Δ͜ͱ΋Ͱ͖Δ   assert  c()  ==  "Hello,  Closure!"
  26. ΫϩʔδϟɿΫϩʔδϟͰͷҾ਺ͷड͚औΓ //  Ҿ਺ͳ͠   def  c0  =  {-­‐>    

         "Hello,  Closure!"   }   assert  c0.call()  ==  "Hello,  Closure!"   //  Ҿ਺1ͭ   def  c1  =  {  String  name  -­‐>          "Hello,  ${name}!"   }   assert  c1.call("Closure")  ==  "Hello,  Closure!"   //  Ҿ਺2ͭʢยํΛܕলུͯ͠ΈΔʣ   def  c2  =  {  greeting,  String  name  -­‐>          println  "${greeting},  ${name}!"   }   assert  c2.call("Hello",  "Closure")  ==  "Hello,  Closure!"   //  Ҿ਺એݴ෦ʮxx..  -­‐>ʯΛলུͨ͠৔߹ɺ҉໧Ҿ਺ͷʮitʯ͕࢖͑Δ   def  c  =  {  "Hello,  ${it}!"  }   assert  c.call("Closure")  ==  "Hello,  Closure!"   assert  c.call()  ==  "Hello,  null!"  //  Ҿ਺Λলུ࣌͸null
  27. ΫϩʔδϟɿΫϩʔδϟΛҾ਺ͱͯ͠౉͢ //  ౉͞ΕͨΫϩʔδϟΛࢦఆ͞ΕͨnameͰ࣮ߦ͢Δ͚ͩͷϝιου   def  justDoIt(String  name,  Closure  closure)  {

             closure.call(name)   }   //  ී௨ʹؙׅހͷதʹΫϩʔδϟΛॻ͍ͨ৔߹   justDoIt("Taro",  {  name  -­‐>  println  "Hello,  ${name}!"  })  //=>  Hello,  Taro!   //  ࠷ޙͷҾ਺͕Ϋϩʔδϟͷ৔߹͸͜ͷΑ͏ʹؙׅހͷ֎ʹग़ͯ͠ॻ͚Δ   justDoIt("Taro")  {  name  -­‐>  println  "Hello,  ${name}!"  }    //=>  Hello,  Taro!   //  ͜ͷΑ͏ʹɺઐ༻ͷจ๏͕͋Δ͔ͷΑ͏ʹಠࣗAPIΛఆٛͰ͖Δ   justDoIt("Taro")  {  name  -­‐>          println  "Hello,  ${name}!"   } ࠷ޙͷҾ਺͕ClosureܕͰ͋Δͱ͜Ζ͕ϙΠϯτ
  28. ʢࢀߟʣΫϩʔδϟɿߴ֊ؔ਺ͱϨΩγΧϧείʔϓͷྫ def  createIdGenerator(prefix)  {    //  ͜ͷ࣮Ҿ਺ͱ      

       int  counter  =  1                            //  ͜ͷϩʔΧϧม਺͕ʢfinalͰ͸ͳ͍ʂʣ          Closure  c  =  {                  "${prefix}-­‐${counter++}"  //  Ϋϩʔδϟ͝ͱʹݸผʹอ࣋͞ΕΔ          }          return  c  //  ΫϩʔδϟΛฦ͢   }   def  genA  =  createIdGenerator("A")   assert  genA()  ==  "A-­‐1"   assert  genA()  ==  "A-­‐2"   assert  genA()  ==  "A-­‐3"   def  genB  =  createIdGenerator("B")   assert  genB()  ==  "B-­‐1"   assert  genB()  ==  "B-­‐2"   assert  genB()  ==  "B-­‐3"   assert  genA()  ==  "A-­‐4" ݩʑcreateIdGeneraterϝιου ͷϩʔΧϧม਺Ͱ͋Δcounter ͕ɺΫϩʔδϟ͝ͱʹݸผʹ؅ ཧ͞Ε͍ͯΔͷ͕Θ͔Δ
  29. BTTFSUΩʔϫʔυ1PXFS"TTFSU 4QPDL͔Βਖ਼ࣜ࠾༻ͨ͠1PXFS"TTFSU͕࢖͑Δ 4QPDLͷํ͕ߋʹઌʹਐΜͰ͍ͯएׯߴػೳʢద߹཰Λදࣔ͢Δͱ͔ʣ Assertion  failed:     assert  a.collect  {

     it  *  2  }.reverse()  ==  [6,  4,  0]                |  |                                    |                  |                |  [2,  4,  6]                    [6,  4,  2]  false                [1,  2,  3]     at  ConsoleScript78.run(ConsoleScript78:2) //  Θ͟ͱ3ͭ໨Λؒҧ͑ͯΈΔ   def  a  =  [1,  2,  3]   assert  a.collect  {  it  *  2  }.reverse()  ==  [6,  4,  0]
  30. ίϨΫγϣϯૢ࡞ɿϦετ List  l  =  [1,  2,  3,  4,  5]  

    //  ֤ཁૉʹରͯ͠ΫϩʔδϟͷॲཧΛద༻͢Δ   l.each  {  number  -­‐>  print  number  }  //=>  12345   //  ֤ཁૉʹରͯ͠ΫϩʔδϟͷॲཧΛద༻ͨ݁͠ՌͷϦετΛऔಘ͢Δ   assert  l.collect  {  it  *  2  }  ==  [2,  4,  6,  8,  10]   //  ֤ཁૉʹରͯ͠ΫϩʔδϟͷॲཧΛద༻ͨ݁͠Ռ͕ਅͷཁૉͷΈΛ࢒͢   assert  l.findAll  {  it  %  2  ==  0  }  ==  [2,  4]   //  ࢦఆͨ͠ηύϨʔλͰ݁߹ͨ͠จࣈྻΛฦ͢   assert  l.join(":")  ==  "1:2:3:4:5"   //  ߹ܭ஋Λࢉग़͢Δ   assert  l.sum()  ==  15
  31. ίϨΫγϣϯૢ࡞ɿϚοϓ Map  m  =  [a:  1,  b:  2,  c:  3]

      //  ΫϩʔδϟҾ਺Λ1͚ͭͩએݴ͢ΔͱɺMap.Entry͕ड͚औΕΔ   m.each  {  Map.Entry  entry  -­‐>          print  entry.key  +  entry.value   }  //=>  a1b2c3   //  ΫϩʔδϟҾ਺Λ2ͭએݴ͢ΔͱɺͦΕͧΕΩʔͱ஋͕ड͚औΕΔ   m.each  {  key,  value  -­‐>          print  key  +  value   }  //=>  a1b2c3   //  ֤ཁૉʹରͯ͠ΫϩʔδϟͷॲཧΛద༻ͨ݁͠ՌͷϦετΛऔಘ͢Δ   assert  m.collect  {  "${it.key}:${it.value}"  }  ==  ["a:1",  "b:2",  "c:3"]   //  Ϋϩʔδϟͷฦ͢஋͕࠷΋େ͖͍ཁૉΛऔಘ͢Δ   assert  m.max  {  it.value  }.key  ==  "c" Ϛοϓʹ΋جຊతʹಉ͡API͕༻ҙ͞Ε͍ͯΔ ʢίϨΫγϣϯͷಛੑ্ɺඍົʹ඼ἧ͑͸ҧ͏ʣ
  32. σϑΥϧτJNQPSUࡁΈύοέʔδ ߴස౓Ͱ࢖͏͜ΕΒͷύοέʔδ͸σϑΥϧτͰJNQPSUࡁΈ java.lang.*   java.io.*   java.net.*   java.util.*  

    groovy.lang.*   groovy.util.*   java.math.BigDecimal   java.math.BigInteger   ʢࢀߟʣผ໊Λ͚ͭͯJNQPSU͢Δ͜ͱ΋Ͱ͖Δ import  java.lang.NullPointerException  as  NPE   throw  new  NPE("aliased  import  sample")
  33. (SPPWZ#FBOT +BWB#FBOTʹର͢Δ(SPPWZͷڧԽαϙʔτ ϓϩύςΟʹର͢ΔHFUUFSTFUUFSͷࣗಈੜ੒ class  Book  {        

     String  title   }   def  book  =  new  Book(title:  "ϓϩάϥϛϯάGROOVY")   //  getter͕ࣗಈੜ੒͞Ε͍ͯΔ   assert  book.getTitle()  ==  "ϓϩάϥϛϯάGROOVY"   //  setter͕ࣗಈੜ੒͞Ε͍ͯΔ   book.setTitle("Java͔ΒGroovy΁")   assert  book.getTitle()  ==  "Java͔ΒGroovy΁"
  34. (SPPWZ#FBOT class  GroovyBeansSample  {          public  String

     p  =  "PUBLIC"          final  String  f  =  "FINAL"          String  g  =  "GetterImplemented"          String  getG()  {  "getGͷ໭Γ஋:  $g"  }   }   def  sample  =  new  GroovyBeansSample()   //  publicͳͲΛΞΫηεम০ࢠΛ෇͚Δͱgetter/setter͸ࣗಈੜ੒͞Εͳ͍   sample.getP()          //=>  groovy.lang.MissingMethodException   sample.setP("x")    //=>  groovy.lang.MissingMethodException   //  finalΛ෇͚Δͱsetter͸ࣗಈੜ੒͞Εͳ͍   assert  sample.getF()  ==  "FINAL"   sample.setF("x")    //=>  groovy.lang.MissingMethodException   //  ࣗલͰ࣮૷ͨ͠ΞΫηαϝιου͸ࣗಈੜ੒͞Εͳ͍   assert  sample.getG()  ==  "getGͷ໭Γ஋:  GetterImplemented"   sample.setG("xxx")   assert  sample.getG()  ==  "getGͷ໭Γ஋:  xxx" ৗʹແ৚݅Ͱࣗಈੜ੒͢ΔΘ͚Ͱ͸ͳ͍
  35. (SPPWZ#FBOT ϓϩύςΟΞΫηεͷ؆ུه๏ class  Book  {          String

     title   }   def  book  =  new  Book(title:  "ϓϩάϥϛϯάGROOVY")   //  Πϯελϯεม਺΁ͷ௚઀ࢀরͷΑ͏ʹΈ͑Δ͕getterΛܦ༝͍ͯ͠Δ   assert  book.title  ==  "ϓϩάϥϛϯάGROOVY"   //  Πϯελϯεม਺΁ͷ௚઀୅ೖͷΑ͏ʹΈ͑Δ͕setterΛܦ༝͍ͯ͠Δ   book.title  =  "Java͔ΒGroovy΁"   assert  book.title  ==  "Java͔ΒGroovy΁"   //  getXxx()ͱ͍͏໊લͷҾ਺ͳ͠ͷϝιουͰ͋Ε͹ϓϩύςΟه๏ͰΞΫηεͰ͖Δ   //  ͭ·ΓɺGroovyBeansʹݶΒ໊ͣલن໿͕Ұக͍ͯ͠Ε͹ɺ͜ͷ؆ུه๏͸࢖͑Δ   assert  book.class  ==  book.getClass()
  36. (SBQF .BWFOϦϙδτϦ͔Β௚઀+BSΛμ΢ϯϩʔυ͠ɺ Ϋϥεύεʹ௨͔ͯ͠ΒεΫϦϓτΛ࣮ߦͰ͖Δ μ΢ϯϩʔυͨ͠ϑΝΠϧ͸)0.&HSPPWZHSBQFT ഑Լʹ֨ೲ͞ΕΔ @Grab('org.apache.commons:commons-­‐lang3:3.2')   import  org.apache.commons.lang3.StringUtils  

    List  l  =  [1,  2,  3,  4,  5]   assert  StringUtils.join(l,  ':')  ==  "1:2:3:4:5"   //  ຊ౰͸͜ͷఔ౓ͷॲཧͰ͋Ε͹GDKͰे෼   assert  l.join(':')  ==  "1:2:3:4:5" ޙ൒Ͱࣔ͢αϯϓϧ͸GrapeΛ࢖ͬͯଈ ࣮ߦͰ͖ΔεΫϦϓτܗࣜʹ͍ͯ͠Δ
  37. ศརͳԋࢉࢠ ౳஋ԋࢉࢠ== +BWBͰ͸ΠϯελϯεͷಉҰੑͷͨΊͷ࢖͏͕ɺ(SPPWZͰ͸FRVBMTݺͼग़ ͠ʹͳ͍ͬͯΔ 4USJOHͷൺֱͰී௨ʹ͕࢖͑Δʂ ΠϯελϯεಉҰੑͷνΣοΫʹ͸0CKFDUJT Λ࢖͏ ΤϧϏεԋࢉࢠ?: A  ?:

     B   ࡾ߲ԋࢉࢠA  ?  A  :  B  ͷলུܗ ηʔϑφϏήʔγϣϯԋࢉࢠ?. a?.b?.c()   OVMMͰ͸ͳ͍৔߹ͷΈɺӈଆͷݺͼग़͠Λଓߦ͢Δ ల։υοτԋࢉࢠ*. [a:1,  b:2,  c:3]*.value  ==  [1,  2,  3]   collect  {  it.value  }  ͷ୹ॖܗͷΠϝʔδ #ccc_cd1 Ͱ঺հ͞Ε·ͨ͠! #ccc_cd1 Ͱ঺հ͞Ε·ͨ͠!
  38. Ϩϯδʢൣғʣ ൣғΛද͢ίϨΫγϣϯ HSPPWZMBOH3BOHF ࢝఺ͱऴ఺Λࢦఆͯͦ͠ͷؒͷཁૉΛ*UFSBCMFʹѻ͏ for  (int  i  :  1..9)  {

     //  ด۠ؒ(9ΛؚΉ)          print  i   }   //=>  123456789   for  (int  i  :  1..<9)  {  //  ൒։۠ؒ(9Λؚ·ͳ͍)          print  i   }   //=>  12345678   //  Range#toList()ͰϦετʹม׵Ͱ͖Δ   assert  (1..5).toList()  ==  [1,  2,  3,  4,  5]
  39. ਖ਼نදݱαϙʔτ ਖ਼نදݱΛαϙʔτ͢Δԋࢉࢠ΍Ϧςϥϧ͕͋Δ //  ʮ==~ʯ׬શҰகʹΑΔϚονϯά݁Ռͷਅِ஋Λฦ͢   assert        "abc"

     ==~  /a.c/   assert  !  ("abc"  ==~  /bc/)    //  ෦෼ҰகͰ͸ͳ͍   //  ࣮ࡍ͸ɺMatcher#matches()ͷݺͼग़͠ʹͳ͍ͬͯΔ   assert      "abc".matches(/a.c/)   assert  !  "abc".matches(/bc/)   //  ʮ=~ʯ෦෼ҰகʹΑΔϚονϯά݁ՌͷMatcherΦϒδΣΫτΛฦ͢   assert  "abc"  =~  /a.c/   assert  "abc"  =~  /bc/              //  ෦෼ҰகOK   //  ࣮͸ɺԋࢉࣗମͷ໭Γ஋͸MatcherΦϒδΣΫτʹͳ͍ͬͯΔ   //  Matcher͕ਅِ஋൑ఆ͞ΕΔλΠϛϯάͰɺ   //  Matcher#find()͕ཪͰݺ͹Εͯͦͷ݁Ռ͕ฦ͍ͬͯΔ   assert  ("abc"  =~  /a.c/).getClass()  ==  java.util.regex.Matcher
  40. ࿦ཧ஋(SPPWZ5SVUI (SPPWZͰ͸CPPMFBO#PPMFBOҎ֎ͷ஋ʹ͍ͭͯ΋ɺ ਅِ൑ఆͰ͖Δ assert  !  0        

                                       //  ੔਺:  0͸ِ   assert      1                                            //  ੔਺:  0Ҏ֎͸ਅ   assert  !  []                                          //  Ϧετ:  ۭϦετ͸ِ   assert      ["a"]                                    //  Ϧετ:  ۭϦετҎ֎͸ਅ   assert  !  [:]                                        //  Ϛοϓ:  ۭϚοϓ͸ِ   assert      [key:'value']                    //  Ϛοϓ:  ۭϚοϓҎ֎͸ਅ   assert  !  ""                                          //  จࣈྻ:  ۭจࣈྻ͸ِ   assert      "a"                                        //  จࣈྻ:  ۭจࣈྻҎ֎͸ਅ   assert  !("abcdefg"  =~  /a.*X/)      //  ਖ਼نදݱ:  Ϛον͠ͳ͍ͱِ   assert      "abcdefg"  =~  /cde/          //  ਖ਼نදݱ:  Ϛον͢Δͱਅ   assert  !  null                                      //  null͸ِ   assert      new  Object()                      //  ͦΕҎ֎ͷΦϒδΣΫτ:  nullҎ֎͸ਅ
  41. ԋࢉࢠΦʔόʔϩʔυ (SPPWZͰ͸+BWBͱಉ౳ͷ֤छԋࢉࢠ͕࢖͑Δ ࣮͸ɺͦΕͧΕͷԋࢉࢠ͸ରԠ͢Δಛఆͷϝιουݺͼग़͠ʹม׵͞Ε͍ͯΔ ͭ·ΓɺԋࢉࢠΦʔόϩʔυ͕Մೳ (%,Ͱ΋ଟ਺׆༻͞Ε͍ͯΔ ྫ͑͹ɺʮ ʯˠʮQMVT ʯɺʮʯˠʮNJOVT ʯɺʮʯˠʮMFGU4IJGU ʯ

    ԋࢉࢠͱରԠ͢ΔϝιουͷҰཡ IUUQHSPPWZMBOHPSHPQFSBUPSTIUNM0QFSBUPS0WFSMPBEJOH class  MyObject  {          String  name          MyObject(name)  {  this.name  =  name  }          MyObject  plus(MyObject  o)  {                  return  new  MyObject(name  +  ":"  +  o.name)          }   }   def  obj1  =  new  MyObject("OBJECT_1")   def  obj2  =  new  MyObject("OBJECT_2")   def  obj3  =  obj1  +  obj2   assert  obj3.name  ==  "OBJECT_1:OBJECT_2"
  42. "45ม׵!(SBCͱ!-PH //  MavenηϯτϥϧϦϙδτϦ͔Βμ΢ϯϩʔυˍΫϥεύεʹࢦఆ   @Grab("log4j:log4j")   import  groovy.util.logging.Log4j   @Log4j

      class  Sample  {          def  doIt()  {                  //  ϩΨʔͱͯ͠logม਺͕࢖͑Δ                  log.fatal  "Hello"          }   }   new  Sample().doIt()   //=>  FATAL  -­‐  Hello
  43. "45ม׵!4JOHMFUPO @groovy.lang.Singleton   class  Sample  {        

     String  value   }   //  ΠϯελϯεॳظԽػߏͱgetInstance()Ϋϥεϝιου͕   //  ௥Ճ͞ΕΔͷͰɺγϯάϧτϯͱ͙ͯ͢͠ʹ࢖͑Δ   assert  Sample.getInstance().value  ==  null   Sample.instance.value  =  "γϯάϧτϯ"   assert  Sample.instance.value  ==  "γϯάϧτϯ"   //  ΋ͪΖΜಉҰΠϯελϯε   assert  sample.instance.is(Sample.instance)
  44. "45ม׵!*NNVUBCMF @groovy.transform.Immutable   class  Sample  {        

     String  value   }   def  sample  =  new  Sample(value:  "HOGE")   sample.value  =  "มߋͰ͖ͳ͍"   //=>  groovy.lang.ReadOnlyPropertyException:   //          Cannot  set  readonly  property:  value  for  class:  Sample  
  45. "45ม׵!5P4USJOH !&RVBMT"OE)BTI$PEF ˏ5VQMF$POTUSVDUPST @groovy.transform.TupleConstructor   @groovy.transform.ToString   @groovy.transform.EqualsAndHashCode   class

     Sample  {          String  a          String  b          int  c   }   //  @TupleConstructorʹΑͬͯએݴͨ͠ϑΟʔϧυͷॱʹҾ਺Λड͚औΔίϯετϥΫλ͕ੜ੒͞ΕΔ   def  sample  =  new  Sample("A",  "B",  3)   //  @ToStringʹΑͬͯͦΕͬΆ͍จࣈྻΛߏ੒͢ΔtoString()͕ੜ੒͞ΕΔ   println  sample.toString()  //  =>  Sample(A,  B,  3)   //  @EqualsAndHashCodeʹΑͬͯɺϓϩύςΟͷ஋Λϕʔεʹͨ͠౳஋൑ఆΛ͢Δequals()͕ੜ੒͞ΕΔ   assert  sample  ==  new  Sample("A",  "B",  3)   assert  sample  !=  new  Sample("A",  "B",  123)   //  ΋ͪΖΜɺequals()ͷ࣮૷ܖ໿ͱͯ͠ඞਢͰ͋ΔhashCode()΋߹Θ࣮ͤͯ૷͞Ε͍ͯΔ   assert  sample.hashCode()  ==  new  Sample("A",  "B",  3).hashCode()   assert  sample.hashCode()  !=  new  Sample("A",  "B",  123).hashCode()   //  (ࢀߟ)  @Canonical͸ɺ@ToStringͱ@EqualsAndHashCodeͷ૊Έ߹ΘͤͷΤΠϦΞε
  46. ੩త(SPPWZˏ5ZQF$IFDLFE class  MyList  {          private  List<String>

     list  =  []                      def  store(name)  {                  list  <<  name          }   }   def  list  =  new  MyList()   list.store  "A"   list.store  "B"   list.store  "C"   println  list.dump()   //=>  <MyList@5c042a81  list=[A,  B,  C]> StringΠϯελϯεΛObjectܕͰ ड͚ͱͬͯɺlistʹ௥Ճ͢Δ ظ଴௨Γಈ͘
  47. ੩త(SPPWZˏ5ZQF$IFDLFE class  MyList  {          private  List<String>

     list  =  []                    @groovy.transform.TypeChecked          def  store(name)  {                  list  <<  name          }   }   def  list  =  new  MyList()   list.store  "A"   list.store  "B"   list.store  "C"   println  list.dump()   //=>  [Static  type  checking]  -­‐  Cannot  call  <T>  java.util.List   <String>#leftShift(T)  with  arguments  [java.lang.Object]      at  line:  7,  column:  9 ίϯύΠϧ࣌ʹΤϥʔ͕ൃੜ͢Δ ͜ͷϝιουΛ ੩తܕνΣοΫ͢Δͱ...
  48. ੩త(SPPWZˏ5ZQF$IFDLFE class  MyList  {          private  List<String>

     list  =  []                    @groovy.transform.TypeChecked          def  store(String  name)  {                  list  <<  name          }   }   def  list  =  new  MyList()   list.store  "A"   list.store  "B"   list.store  "C"   println  list.dump()   //=>  <MyList@5c042a81  list=[A,  B,  C]> StringܕΛ໌ࣔ͢Δͱ... ·ͨಈ͘Α͏ʹͳͬͨʂ
  49. ੩త(SPPWZඇ!$PNQJMF4UBUJD long  fib(long  n)  {          if

     (n  <  2)  return  1          return  fib(n  -­‐  2)  +  fib(n  -­‐  1)   }   def  start  =  System.currentTimeMillis()   def  num  =  40   def  ans  =  fib(num)   println  "fib($num)  =  ${ans}"   println  "Total:  ${System.currentTimeMillis()  -­‐  start}  msec"   //=>  fib(40)  =  165580141   //      Total:  1575  msec
  50. ੩త(SPPWZ!$PNQJMF4UBUJD import  groovy.transform.CompileStatic   @CompileStatic   long  fib(long  n)  {

             if  (n  <  2)  return  1          return  fib(n  -­‐  2)  +  fib(n  -­‐  1)   }   def  start  =  System.currentTimeMillis()   def  num  =  40   def  ans  =  fib(num)   println  "fib($num)  =  ${ans}"   println  "Total:  ${System.currentTimeMillis()  -­‐  start}  msec"   //=>  fib(40)  =  165580141   //      Total:  569  msec ໿3ഒʂʻ1575 msec
  51. ʢࢀߟʣ"45ม׵!.FNPJ[FE import  groovy.transform.Memoized   @Memoized   long  fib(long  n)  {

             if  (n  <  2)  return  1          return  fib(n  -­‐  2)  +  fib(n  -­‐  1)   }   def  start  =  System.currentTimeMillis()   def  num  =  40   def  ans  =  fib(num)   println  "fib($num)  =  ${ans}"   println  "Total:  ${System.currentTimeMillis()  -­‐  start}  msec"   //=>  fib(40)  =  165580141   //      Total:  4  msec !!!!!!?????? ʻ569 msec ʻ1575 msec ࢀরಁաͳؔ਺ͷ৔߹ɺ ϝϞԽʢҾ਺ͱ݁Ռͷ૊Έ߹Θͤ ΛΩϟογϡʣͷޮՌ͕ڧྗʹ׆ ༻Ͱ͖Δ৔߹͕͋Δ
  52. NBJOϝιου࣋ͭΫϥε //  in  HelloMain.groovy   class  HelloMain  {    

         static  void  main(String...  args)  {                  println  "Hello,  Main!"          }   }   //=>  Hello,  Main!
  53. (SPPWZεΫϦϓτ //  in  hello.groovy   println  "Hello,  Script!"   //=>

     Hello,  Script! Ϋϥεͷ֎ଆͷϧʔτϨϕϧͰ௚઀ίʔυ ͕ॻ͔Ε͍ͯΔʹGroovyεΫϦϓτ ͪͳΈʹɺίϯύΠϧ͞ΕΔͱɺ ScriptΫϥεͷΠϯελϯεʹͳΔ public  class  hello  extends  groovy.lang.Script  {      public  static  transient  boolean  __$stMC;      public  hello();      public  hello(groovy.lang.Binding);      public  static  void  main(java.lang.String...);      public  java.lang.Object  run();      protected  groovy.lang.MetaClass  $getStaticMetaClass();   }
  54. +6OJUͷςετέʔε //  in  HelloTest.groovy   import  junit.framework.TestCase   class  HelloTest

     extends  TestCase  {          void  testHello()  {                  println  "Hello,  JUnit!"          }   }   //=>  .Hello,  JUnit!   //   //      Time:  0.047   //   //      OK  (1  test)   // Groovy͕JUnitΛಉ͍ࠝͯ͠ΔͷͰ ผ్JARΛ༻ҙ͢Δඞཁ͸ͳ͍
  55. 3VOOBCMFͷ࣮૷Ϋϥε //  in  HelloRunnable.groovy   class  HelloRunnable  implements  Runnable  {

             void  run()  {                  println  "Hello,  Runnable!"          }   }   //=>  Hello,  Runnable!
  56. ͓ࢼ͠؀ڥ HSPPWZ$POTPMF্Ͱࢼ͢ γϯϓϧͳΤσΟλͰࢼߦࡨޡͰ͖Δ (SBQFΛ࢖ͬͯαʔυύʔςΟϥΠϒϥϦ΋ࢼͤΔ Θ͔Γ΍͓ͯ͘͢खܰ HSPPWZTIͰࢼ͢ +BWBͱ(SPPWZͷඪ४"1*Ͱ͋Ε͹ɺ5BCʹΑΔίʔυิ׬ ͕ޮ͘఺Ͱͪΐͬͱศར ΤσΟλʴHSPPWZ PS(SPPWZ4FSW

     ΤσΟλͷػೳͰ͙͢ʹ࣮ߦͰ͖Δ؀ڥΛͭ͘Δͱศར ʢྫʣWJN RVJDLSVOWJN (SPPWZ4FSW IUUQOPCFBOTIBUFOBCMPHDPNFOUSZ ͪͳΈʹɺ͜ͷࢿྉͷαϯϓϧίʔυ͸ ΄ͱΜͲgroovyConsoleͰॻ͖·ͨ͠
  57. 9.-1BSTFSͰଐੑ΍ςΩετΛࢀর͢Δྫ def  inputXml  =  """   <root>      <items>

             <item  id="1"  name="͍͋͏͓͑">OK</item>          <item  id="2"  name="͔͖͚͘͜">NG</item>          <item  id="3"  name="ͤͦ͢͞͠">OK</item>      </items>   </root>   """   def  root  =  new  XmlParser().parseText(inputXml)  //  <root>ʹରԠ͢Δgroovy.util.NodeΦϒδΣΫτ   //  ͢΂ͯͷitemཁૉΛϑΥʔϚοτͯ͠ग़ྗ͢Δ   root.items.item.each  {  Node  item  -­‐>          println  "${item.@id}:  ${item.@name}  =>  ${item.text()}"   }   //=>  1:  ͍͋͏͓͑  =>  OK   //      2:  ͔͖͚͘͜  =>  NG   //      3:  ͤͦ͢͞͠  =>  OK   //  OKͷitemཁૉͷΈΛϑΥʔϚοτͯ͠ग़ྗ͢Δ   root.items.item.findAll  {  it.text()  ==  "OK"  }.each  {          println  "${it.@id}:  ${it.@name}  =>  ${it.text()}"   }   //=>  1:  ͍͋͏͓͑  =>  OK   //      3:  ͤͦ͢͞͠  =>  OK ͜ͷ࣌఺ͰXML͸ύʔε͞Εͯɺ NodeπϦʔ͕ϝϞϦ্ʹల։ࡁΈ GPathͱ͍͏ه๏ͰNodeͷίϨΫγϣϯΛಛఆ ଐੑ஋͸ʮ@ʴଐੑ໊ʯɺ ࢠཁૉͷςΩετ͸ʮtext()ʯͰࢀর each, findAllͳͲͷίϨΫγϣϯૢ࡞͕ ͦͷ··ద༻Ͱ͖Δ
  58. Ϛοϓͷ৘ใΛݩʹ)5.-Λग़ྗ͢Δྫ def  generateHtml  =  {  data,  writer  -­‐>    

     def  reportTitle  =  'ࢼݧ࣮ࢪ೔࣌ใࠂ'      def  formatCount  =  {  now,  latest  -­‐>          def  diffCount  =  now  -­‐  latest          return  "${now}  (${diffCount  >  0  ?  "+"  :  ""}${diffCount})"      }      new  groovy.xml.MarkupBuilder(writer).html  {          head  {              title  reportTitle          }          body(style:  "background:  #afa")  {              h1  reportTitle              h2  'ࢼݧ݅਺౳'              ul  {                  li  "ࢼݧ߲໨਺:  ${formatCount(data.tests,  data.latest.tests)}"                  li  "ऴྃ݅਺:  ${formatCount(data.done,  data.latest.done)}"                  li  "όά݅਺:  ${formatCount(data.issues,  data.latest.issues)}"              }              h2  'උߟ'              if  (data.remarks)  {                  ul  {                      data.remarks.each  {                          li(it)      }  }  }  }  }   }   def  data  =  [      tests:  1230,  done:      350,  issues:  123,      latest:  [tests:  1235,  done:      320,  issues:  93],      remarks:  ["ਐḿ͸ಛʹ໰୊ͳ͠",  "ΠϯϑϧΤϯβ͕ྲྀߦதͳͷͰෆ҆"]   ]   new  File("/tmp/daily-­‐test-­‐report.html").withWriter  {  writer  -­‐>      generateHtml(data,  writer)   }
  59. Ϛοϓͷ৘ใΛݩʹ)5.-Λग़ྗ͢Δྫ    //...      new  groovy.xml.MarkupBuilder(writer).html  {    

         head  {              title  reportTitle          }          body(style:  "background:  #afa")  {              h1  reportTitle              h2  'ࢼݧ݅਺౳'              ul  {                  li  "ࢼݧ߲໨਺:  ${formatCount(data.tests,  data.latest.tests)}"                  li  "ऴྃ݅਺:  ${formatCount(data.done,  data.latest.done)}"                  li  "όά݅਺:  ${formatCount(data.issues,  data.latest.issues)}"              }              h2  'උߟ'              if  (data.remarks)  {                  ul  {                      data.remarks.each  {                          li(it)      }  }  }  }  }      //...
  60. .BSLVQ#VJMEFSʹ͍ͭͯ΋͏গ͠ิ଍ def  builder  =  new  groovy.xml.MarkupBuilder()   def  existMethod(a)  {

     "EXIST_METHOD:  ${a}"  }   //  ࠷ॳͷݺͼग़͠Ͱ࢖໊ͬͨલ͕ϧʔτཁૉͷλά໊ʹͳΔ   builder.aaa  {          //  ଘࡏ͠ͳ͍ϝιου໊Ͱݺͼग़͢ͱཁૉએݴͱݟͳ͞ΕΔɻҾ਺͸ࢠཁૉʹͳΔɻ          bbb  "BBB"                    //  Ҿ਺ΛϚοϓͰࢦఆ͢Δͱଐੑ஋ʹͳΔ          ccc(c1:  "C1",  c2:  "C2")          //  Ҿ਺ͱͯ͠ΫϩʔδϟΛ౉͢ͱωετʹͳΔ          ddd  {                  xxx  "XXX"          }          //  ੍ޚߏจ͕ͦͷ··࢖͑Δ          if  (false)  {                  //  ͕࣮͜͜ߦ͞Εͳ͚Ε͹ग़ྗ͞Εͳ͍                  ignoredThis  "IGNORED"          }                    //  ଘࡏ͢ΔϝιουͰ͋Ε͹୯ʹͦͷϝιου͕ݺ͹ΕΔ͚ͩͰཁૉ͸ੜ੒͞Εͳ͍          //  ଘࡏ͠ͳ͍ϝιουΛ࣮ߦ͠Α͏ͱ͢Δ͜ͱ͕ɺཁૉੜ੒ͷτϦΨͱͳΔ          existMethod  "ͨͩͷϝιουݺͼग़͠"   } <aaa>      <bbb>BBB</bbb>      <ccc  c1='C1'  c2='C2'  />      <ddd>          <xxx>XXX</xxx>      </ddd>   </aaa>   ͜ͷΑ͏ʹɺGroovyͷʮ*Builderʯ͸ଘࡏ͠ͳ ͍ϝιουݺͼग़͠ʢmethodMissingʣΛτϦΨ ʹͯ͠ߏ଄ΛϏϧυ͍ͯ͘͠Ϋϥεʹͳ͍ͬͯΔ
  61. )5.-εΫϨΠϐϯά63-HFU5FYU String  html  =  new  URL("http://groovy-­‐lang.org/").text   //  1ߦͣͭνΣοΫͯ͠URLΛύʔε͢Δ  

    def  urls  =  html          //  1ߦͣͭͷϦετʹ͢Δ          .readLines()          //  ߦதʹURLύλʔϯ͕͋ͬͨΒͦΕΛฦ͢ʢͳ͚Ε͹nullʣ          .collect  {  line  -­‐>                  if  (line  =~  $/.*(https?://[a-­‐zA-­‐Z0-­‐9%?._]+).*/$)  {                          return  java.util.regex.Matcher.lastMatcher.group(1)                  }          }          //  nullΛআ֎͢Δ          .findAll  {  it  !=  null  }          //  ॏෳͨ͠URLΛআڈ͢Δ          .unique()   //  ιʔτͯ͠දࣔ͢Δ   urls.sort().each  {  println  it  }
  62. )5.-εΫϨΠϐϯά9NM1BSTFS /FLP)5.- @Grab('net.sourceforge.nekohtml:nekohtml:1.9.21')   import  org.cyberneko.html.parsers.SAXParser   import  groovy.util.Node  

    def  parser  =  new  XmlParser(new  SAXParser())   Node  html  =  parser.parse("http://groovy-­‐lang.org/")   //  1ߦͣͭνΣοΫͯ͠URLΛύʔε͢Δ   def  urls  =  html          //  html഑Լͷ͢΂ͯͷࢠཁૉͷaλάͷhrefଐੑ஋ΛूΊΔ          .'**'.A.@href          //  http(s)ͷ΋ͷ͚ͩநग़͢Δ          .findAll  {                    it  ==~  /https?:.*/          }          //  ॏෳͨ͠URLΛআڈ͢Δ          .unique()   //  ιʔτͯ͠දࣔ͢Δ   urls.sort().each  {  println  it  }
  63. )5.-εΫϨΠϐϯάKTPVQ @Grab('org.jsoup:jsoup:1.8.1')   import  org.jsoup.Jsoup   import  org.jsoup.nodes.Document   Document

     doc  =  Jsoup.connect("http://groovy-­‐lang.org/").get()   def  urls  =  doc          //  ͢΂ͯͷaλάͷhrefଐੑΛूΊΔ          .select('a')*.attr("href")          //  http(s)ͷ΋ͷ͚ͩநग़͢Δ          .findAll  {                    it  ==~  /https?:.*/          }          //  ॏෳͨ͠URLΛআڈ͢Δ          .unique()   //  ιʔτͯ͠දࣔ͢Δ   urls.sort().each  {  println  it  }
  64. (SPPWZ42-Ͱ)Λૢ࡞͢Δ @Grab('com.h2database:h2')   @GrabConfig(systemClassLoader=true)  //  JDBC͸γεςϜΫϥεϩʔμ͔Β୳͞ΕΔͷͰඞཁ   import  groovy.sql.Sql  

    //  ผ్DataSource΍ConnectionΛ༻ҙ͢ΔͳΒɺSqlͷίϯετϥΫλʹ౉ͤ͹OK   def  db  =  Sql.newInstance("jdbc:h2:mem:sample",  "org.h2.Driver")   //  Sql#execute()ͰDDLΛ࣮ߦ͢Δ   db.execute  """   create  table  person  (          name  varchar(255),          age  int   )   """   //  Sql#executeUpdate()࢖͏ͱɺมߋͨ͠ߦ਺͕ฦΔ   insertSql  =  "insert  into  person  (name,  age)  values  (?,  ?)"   assert  db.executeUpdate(insertSql,  ['Mike',    13])  ==  1   assert  db.executeUpdate(insertSql,  ['Junko',  14])  ==  1   //  Sql#eachRow()͸1ߦ͝ͱʹॲཧ͢Δ(Ϧιʔε௿ෛՙ)   db.eachRow('select  *  from  person')  {  row  -­‐>          println  row.name   }   //=>  Mike   //      Junko   //  Sql#rows()͸݁ՌΛ͢΂ͯϝϞϦ্ʹऔಘ͢Δ(Ϧιʔεߴෛՙ)   println  db.rows('select  *  from  person').collect  {  it.name  }   //=>  [Mike,  Junko]
  65. %BUB4FUΛ࢖͏ྫ @Grab('com.h2database:h2')   @GrabConfig(systemClassLoader=true)  //  JDBC͸γεςϜΫϥεϩʔμ͔Β୳͞ΕΔͷͰඞཁ   import  groovy.sql.Sql  

    //  ผ్DataSource΍ConnectionΛ༻ҙ͢ΔͳΒɺSqlͷίϯετϥΫλʹ౉ͤ͹OK   def  db  =  Sql.newInstance("jdbc:h2:mem:sample",  "org.h2.Driver")   //  Sql#execute()ͰDDLΛ࣮ߦ͢Δ   db.execute("""   create  table  person  (          name  varchar(255),          age  int   )   """)   //  DataSetΛ࢖͏ͱίϨΫγϣϯΦϒδΣΫτ෩ʹϨίʔυૢ࡞͕Ͱ͖Δ   import  groovy.sql.DataSet   DataSet  people  =  db.dataSet('person')   people.add(name:  'Mike',  age:13)   people.add(name:  'Junko',  age:  14)   people.add(name:  'Ken',  age:  23)   people.each  {          println  "${it.name}  (${it.age})"   }   //=>  Mike  (13)   //      Junko  (14)   //      Ken  (23)
  66. (&YDFM"1* @GrabResolver(name="bintray",  root="http://dl.bintray.com/nobeans/maven")   @Grab("org.jggug.kobo:gexcelapi:0.4")   import  org.jggug.kobo.gexcelapi.GExcel   def

     book  =  GExcel.open("/tmp/sample.xlsx")   def  sheet  =  book[0]    //  1γʔτ໨   //  Excel෩ͳDSLͰηϧͷ஋Λऔಘ͢Δ   println  sheet.A1.value    //=>  A1ͷ஋   println  sheet.B2.value    //=>  B2ͷ஋   println  sheet.C3.value    //=>  303.0   println  sheet.D4.dateCellValue.format("yyyy-­‐MM-­‐dd")  //=>  2015-­‐02-­‐29   //  ࢦఆۣͨ͠ܗ಺ͰΠςϨʔγϣϯ   sheet.A1_D4.each  {  row  -­‐>          println  row   }   //=>  [[A1ͷ஋,  B1ͷ஋,  301.0,  42041.0],   //        [A2ͷ஋,  B2ͷ஋,  302.0,  42042.0],   //        [A3ͷ஋,  B3ͷ஋,  303.0,  42043.0],   //        [A4ͷ஋,  B4ͷ஋,  304.0,  42044.0]] ೔෇ܕͷηϧ͸ϓϩάϥϚ͕೔෇Ͱ͋Δ͜ ͱΛҙࣝͯ͠औಘ͠ͳ͚Ε͹ͳΒͳ͍
  67. ෳ਺ߦจࣈྻϦςϥϧʴTUSJQ.BSHJO String  applyTemplate(name,  title)  {          return

     """\                  |͜Μʹͪ͸ɺ${name}͞Μ                  |                  |ຊ೔͸ɺ${title}Λ͝Ҋ಺͍͖ͤͯͨͩ͞·͢ɻ                  |...                  |""".stripMargin()   }   println  applyTemplate("೔ຊ  ଠ࿠",  "ϓϩάϥϛϯάGROOVY")   //=>  ͜Μʹͪ͸ɺ೔ຊ  ଠ࿠͞Μ   //   //      ຊ೔͸ɺϓϩάϥϛϯάGROOVYΛ͝Ҋ಺͍͖ͤͯͨͩ͞·͢ɻ   //      ... ઌ಄ߦͷΤεέʔϓ෇͖վߦͱ stripMarginΛ࢖͏͜ͱͰɺ ΠϯσϯτΛࣗવͳܗʹἧ͑ΒΕΔ
  68. 4JNQMF5FNQMBUF&OHJOF import  groovy.text.SimpleTemplateEngine   String  applyTemplate(name,  title)  {    

         String  templateText  =  '''\                  |͜Μʹͪ͸ɺ${name}͞Μ                  |                  |ຊ೔͸ɺ<%=  title  %>Λ͝Ҋ಺͍͖ͤͯͨͩ͞·͢ɻ                  |...                  |'''.stripMargin()          def  template  =  new  SimpleTemplateEngine().createTemplate(templateText)   def  binding  =  [name:  name,  title:  title]   return  template.make(binding)   }   println  applyTemplate("೔ຊ  ଠ࿠",  "ϓϩάϥϛϯάGROOVY")   //=>  ͜Μʹͪ͸ɺ೔ຊ  ଠ࿠͞Μ   //   //      ຊ೔͸ɺϓϩάϥϛϯάGROOVYΛ͝Ҋ಺͍͖ͤͯͨͩ͞·͢ɻ   //      ... JSPܗࣜͷม਺ల։΋Ͱ͖Δ ςϯϓϨʔτจࣈྻΛ֎෦ϑΝΠ ϧ͔ΒಡΈࠐΉΑ͏ʹ͢Δͱྑ͍ ʢྫʣnew File("template.tpl").text #ccc_g4 ͰGradle͔Βͷར༻ྫ͕঺հ͞ΕͨΒ͍͠ʁ
  69. ͦͷଞɺࢀߟ63- αϯϓϧίʔυ IUUQTHJUIVCDPNOPCFBOTKKVHDDD TQSJOHHSPPWZ (SPPWZ)PNF IUUQHSPPWZMBOHPSH (SPPWZ+%, IUUQEPDTHSPPWZMBOHPSHEPDTMBUFTU IUNMHSPPWZKEL (SPPWZԋࢉࢠΦʔόϩʔυ

    IUUQHSPPWZMBOHPSH PQFSBUPSTIUNM0QFSBUPS0WFSMPBEJOH (7. IUUQHWNUPPMOFU (SPPWZ4FSW IUUQLPCPHJUIVCJPHSPPWZTFSW (&YDFM"1* IUUQTHJUIVCDPNOPCFBOTHFYDFMBQJ /FLP)5.- IUUQOFLPIUNMTPVSDFGPSHFOFU KTPVQ IUUQKTPVQPSH ϓϩάϥϛϯά(3007:ผ࡭ɿୈ̔ষ (SPPWZ ͷ৽ػೳ IUUQCFUBNZCFUBCPPLDPNTIPXQBHF DG⒎CCCC ࣮༻తͳ(SPPWZ+BWBΞϓϦέʔγϣϯʹ (SPPWZΛࠞͥࠐΉ IUUQXXXJCNDPNEFWFMPQFSXPSLTKQ KBWBMJCSBSZKQH &NCFEEJOH(SPPWZʢ+BWB͔Β(SPPWZΛ࢖ ͏ʣ IUUQHSPPWZDPEFIBVTPSH&NCFEEJOH (SPPWZ (SPPWZͷ࢖͍Ͳ͜Ζʙͭͷಋೖύλʔϯʙ IUUQXXXTMJEFTIBSFOFUOPCFBOTUIF SFQPSUPGKBWBPOFBCPVUHSPPWZ