SlideShare a Scribd company logo
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.1
2015年 4月 18日
JGGUG/NTTソフトウェア株式会社
上原潤二
今さら始めよう
Groovy
渋谷JVM
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
わたくしは
上原潤二(@uehaj)
NTTソフトウェア(株)Grails推進室
JGGUG運営委員
書籍:
プログラミングGROOVY(技術評論社)
Grails徹底入門(翔泳社)
ブログ「Grな日々」
2
ElmとRust
推してます
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
お品がき
Groovyってどんな言語?
Groovyの思想
Groovyはどう役立つのか?
今どきのGroovy
3
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.4
Groovyって
どんな言語?
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Groovyってどんな言語?(1)
文法はJavaのほぼ上位互換
真のクロージャを持ち簡潔な記述を旨とする
型システム・型チェック
Groovy 1.8までは実行時型チェックのみ、
Groovy 2.0からは静的型チェック・静的コンパイル
→Javaに準じた静的なコードも吐ける
5
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Groovyってどんな言語?(2)
実行
Groovy コードはJava バイトコード(クラス)に
常にコンパイルされて実行される
ラッパーや特殊なコンテキストやインタプリタ無し
ライブラリ
独自の体系はもたず、 Java 標準 API を基本と
して Groovy 独自のクラスやメソッドを追加
6
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.7
2003 2004 2005 2006 2007 2008
1.51.0 1.1
Groovy
1.0b4
JSR化
Groovy
1.0b10
JSR EA
JSR-6 1.6-rc
JSR化
2009 2010 2011 2012 2013 2014 2015
→G2One
Groovy
1.7
Groovy
1.8
Groovy
2.0
Static Compilation
Groovy
2.4
Android Support
→SpringSource
→VMWare
→Pivotal
7月
Grails 0.3
Spock 0.1
Gradle 0.7
Grails 3.0
Groovyの歴史
JGGUG開始
AST変換
indy
今のGroovy基本
Groovy
2.5
Apache
ASF
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
最近の話題
Pivotal社がスポンサーを降板(∼2015/3末)
Groovy/Grailsコア開発メンバーの直接雇用終了
codehaus閉鎖もあり、GroovyはASF傘下の
インキュベータープロジェクトに
8
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
こんな感じのやりとり(想像です)
9
ぼくと契約して、ASF
プロジェクトになって
よ!
きゅうべえ、いや
(Apache)インキュベー
ター!!!
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Java7コード例(WordCount)
10
import	
  java.util.Comparator;	
  
	
  import	
  java.util.HashMap;	
  
	
  import	
  java.util.Map;	
  
	
  import	
  java.util.Set;	
  
	
  import	
  java.util.List;	
  
	
  import	
  java.util.ArrayList;	
  
	
  import	
  java.util.Collections;	
  
	
  import	
  java.io.FileReader;	
  
	
  import	
  java.io.BufferedReader;	
  
	
  import	
  java.io.IOException;	
  
	
  	
  
	
  public	
  class	
  WordCount7	
  {	
  
	
  	
  public	
  static	
  void	
  main(String[]	
  args)	
  	
  
	
  	
  	
  	
  	
  	
  throws	
  IOException	
  {	
  
	
  	
  	
  try	
  (FileReader	
  fis	
  =	
  new	
  FileReader(args[0]);	
  
	
  	
  	
  	
  	
  	
  BufferedReader	
  br	
  =	
  new	
  BufferedReader(fis))	
  {	
  
	
  	
  	
  	
  Map<String,	
  Integer>	
  map	
  =	
  new	
  HashMap<>();	
  
	
  	
  	
  	
  String	
  line;	
  
	
  	
  	
  	
  while	
  ((line	
  =	
  br.readLine())	
  !=	
  null)	
  {	
  
	
  	
  	
  	
  	
  for	
  (String	
  it:	
  line.split("W+"))	
  {	
  
	
  	
  	
  	
  	
  	
  map.put(it,	
  (map.get(it)==null)	
  ?	
  1	
  :	
  
(map.get(it)	
  +	
  1));	
  
	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  }	
  
	
  	
  	
  	
  List<Map.Entry<String,	
  Integer>>	
  entrySetList	
  
	
  	
  	
  	
  	
  	
  =	
  new	
  ArrayList<>(map.entrySet());	
  
	
  	
  	
  	
  Comparator<Map.Entry<String,	
  Integer>>	
  comp	
  =	
  
	
  	
  	
  	
  	
  new	
  Comparator<Map.Entry<String,	
  Integer>>(){	
  
	
  	
  	
  	
  	
  	
  public	
  int	
  compare(Map.Entry<String,	
  Integer>	
  
o1,	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  Map.Entry<String,	
  Integer>	
  o2)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  return	
  o1.getValue()	
  -­‐	
  o2.getValue();	
  
	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  	
  };	
  
	
  	
  	
  	
  Collections.sort(entrySetList,	
  comp);	
  
	
  	
  	
  	
  for	
  (Map.Entry<String,	
  Integer>	
  entry:	
  
entrySetList)	
  {	
  
	
  	
  	
  	
  	
  System.out.println(entry.getValue()	
  +	
  
":"+entry.getKey());	
  
	
  	
  	
  	
  }	
  
	
  	
  	
  }	
  
	
  	
  }	
  
	
  }	
  
	
  	
  	
  System.out.println(entry.getValue()	
  +	
  
":"+entry.getKey());	
  
	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  	
  }	
  
	
  	
  	
  }	
  
	
  }	
  
	
  	
  
	
  def	
  words	
  =	
  new	
  File(args[0]).text.split(/W+/)	
  
	
  words.countBy{it}.entrySet().sort{it.value}.each	
  {	
  
	
  	
  	
  println	
  "${it.value}:	
  ${it.key}"	
  
	
  }	
  
Groovyコード例(WordCount)
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Java7コード例(Immutable)
11
public	
  final	
  class	
  Punter	
  {	
  
	
  	
  	
  	
  	
  private	
  final	
  String	
  first;	
  
	
  	
  	
  	
  	
  private	
  final	
  String	
  last;	
  
	
  	
  
	
  	
  	
  	
  	
  public	
  Punter(String	
  first,	
  String	
  last)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  this.first	
  =	
  first;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  this.last	
  =	
  last;	
  
	
  	
  	
  	
  	
  }	
  
	
  	
  
	
  	
  	
  	
  	
  public	
  String	
  getFirst()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  first;	
  
	
  	
  	
  	
  	
  }	
  
	
  	
  
	
  	
  	
  	
  	
  public	
  String	
  getLast()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  last;	
  
	
  	
  	
  	
  	
  }	
  
	
  	
  
	
  	
  	
  	
  	
  @Override	
  
	
  	
  	
  	
  	
  public	
  int	
  hashCode()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  final	
  int	
  prime	
  =	
  31;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  int	
  result	
  =	
  1;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  result	
  =	
  prime	
  *	
  result	
  +	
  ((first	
  ==	
  null)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ?	
  0	
  :	
  first.hashCode());	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  result	
  =	
  prime	
  *	
  result	
  +	
  ((last	
  ==	
  null)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ?	
  0	
  :	
  last.hashCode());	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  result;	
  
	
  	
  	
  	
  	
  }	
  
	
  	
  
	
  	
  	
  	
  	
  @Override	
  
	
  	
  	
  	
  	
  public	
  boolean	
  equals(Object	
  obj)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  if	
  (this	
  ==	
  obj)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  true;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  if	
  (obj	
  ==	
  null)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  false;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  if	
  (getClass()	
  !=	
  obj.getClass())	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  false;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  Punter	
  other	
  =	
  (Punter)	
  obj;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  if	
  (first	
  ==	
  null)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  if	
  (other.first	
  !=	
  null)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  false;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  else	
  if	
  (!first.equals(other.first))	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  false;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  if	
  (last	
  ==	
  null)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  if	
  (other.last	
  !=	
  null)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  false;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  }	
  else	
  if	
  (!last.equals(other.last))	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  false;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  true;	
  
	
  	
  	
  	
  	
  }	
  
	
  	
  
	
  	
  	
  	
  	
  @Override	
  
	
  	
  	
  	
  	
  public	
  String	
  toString()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  "Punter(first:"	
  +	
  first	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  +	
  ",	
  last:"	
  +	
  last	
  +	
  ")";	
  
	
  	
  	
  	
  	
  }	
  
	
  }	
  
	
  @Immutable	
  final	
  class	
  Punter	
  {	
  
	
  	
  	
  	
  	
  String	
  first,	
  last	
  
	
  }
Groovyコード例(Immutable)
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Groovyコードの実行
12
JVM
2011
Javaソース
.classファイル
javacコマンド
javaコマンド
標準クラスローダ
Javaクラス
Groovyコード
groovyコマンド
Groovyクラスローダ
(オンメモリ実行時コンパイラ)
JavaクラスJavaクラス
.classファイル
groovycコマンド
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Javaコードの実行
13
JVM
Javaソース
.classファイル
javacコマンド
javaコマンド
標準クラスローダ
Javaクラス
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Groovyコードの実行
146
JVM
標準クラスローダ
Groovyコード
groovyコマンド
Groovyクラスローダ
(オンメモリ実行時コンパイラ)
JavaクラスJavaクラス
.classファイル
groovycコマンド
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
GDK
Groovyのために拡張されたJava API
Collection#each(), Iterator#groupBy()..
File#getText(), File#renameTo()…
String#execute(), String#tr(), ..
15
"ls".execute()
 'こんにちは'.tr('あ-ん', ‘ア-ン')
 new File("tmp.txt") << "hellon"
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
GDKメソッド群
16
クラス GDK追加メソッド数
java.lang.CharSequenc 93
java.io.File 88
java.nio.file.Path 86
java.lang.Iterable 84
java.lang.Object 77
java.util.List 72
java.lang.Object[] 63
java.util.Map 58
java.util.Iterator 54
java.util.Collection 48
: :
Total 1352
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.17
Groovyの
思想
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Groovyの設計思想
「Javaを置き換えない」
Javaとの併用・共存・補完が存在意義そのもの。
GroovyはJavaクラスファイルを別ルート・別記法で読み
込ませるためのクラスローダーであり、ライブラリの一種
でもある。
JavaのAPIやライブラリはGroovyにとって必要悪で
はない。
Javaライブラリは直接もしくは、Groovyラッピング・
拡張し使用
RxGroovy/RxJava, ..
18
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
JRuby想定ユーザタイプ別Groovy乗り換えガイド
JRuby想定ユーザA:
しょうがなくJVMを使う
必要にせまられたrubiest。
JRuby想定ユーザB:
Java APIもJVMも大好き
だがJavaの文法だけは嫌
い。
JRuby想定ユーザC:
RubyのライブラリをJVM
上で使いたいだけの人
Java APIはなるべく呼びませ
ん。Javaは必要悪!
Groovyとの競合の余地ゼロ。
Groovyと思いきり競合
あなたはGroovyを使えばもっ
と幸せになれるかも。
Groovyとの競合の余地ゼ
ロ。
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.20
Groovyはど
う役立つのか?
Grails, Gradle、Spock
など、DSLを実装するツー
ルやFWを通じて利用
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Groovyの主な用途2つ
21
①DSLを実装
するための言語
②Javaスクリ
プティング!
Javaプログラマの日
常の仕事をGroovyで
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.22
Grails, Gradle、Spock
など、DSLを実装するツー
ルやFWを通じて利用
①DSLを実装
するための言語
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
ファクト: DSL実装言語としてのGroovy
Spock
Gradle
Grails
Geb
Jenkins
MarkupTemplateEngine/MarkupBuilder
23
テストコード記述用DSL
Webアプリ記述用DSL
ビルド手順記述用DSL
Selenium2制御用DSL
HTML代替DSL
ワークフロー定義DSL、CLI
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Spockによるテストコード
24
パラメータのバリエーションを表形式で記
述(|はビットOR演算子)
表の1行がそれぞれ別のテストケース(テ
ストメソッド)として実行されたかのように結
果が表示される。
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Why Groovy DSL?
Groovy「Java開発者向けのDSL」に最適
Groovyのシンタックスやセマンティクスが「優れて
いる」必要はない
Java開発者にとって素直にわかればよく、

意表をつく何かが無い方が良い
加えて、
「中括弧言語」としての十分な表現力
高速コンパイル、トライアンドエラーのしやすさ
動的型
25
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
動的型とDSL
「本質的に動的」な対象のDSLモデリングには、

動的型が自然な記述に寄与
26
	
  def	
  slurper	
  =	
  new	
  JsonSlurper()	
  
	
  def	
  result	
  =	
  
slurper.parseText('{"person":
{"name":"Guillaume","age":33,"pets":
["dog","cat"]}}')	
  
	
  assert	
  result.person.name	
  ==	
  
"Guillaume"	
  
	
  assert	
  result.person.age	
  ==	
  33	
  
	
  assert	
  result.person.pets.size()	
  ==	
  2	
  
	
  assert	
  result.person.pets[0]	
  ==	
  "dog"	
  
	
  assert	
  result.person.pets[1]	
  ==	
  "cat"	
  
html	
  {	
  
	
  	
  	
  head	
  {	
  
	
  	
  	
  	
  	
  	
  meta(charset:'utf-­‐8')	
  
	
  	
  	
  	
  	
  	
  title('Page	
  title')	
  
	
  	
  	
  }	
  
}
JSONを対象とした処理 HTMLマークアップ
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Why DSL?
27
加えて、実装⾔言語の都合(⽂文
法・意味)をただ受け⼊入れるの
ではなく、

あるべき記法を追求する
ドメインモデルを書き下
すのに、既存⾔言語の⽂文法
や実装都合の範囲内で、
クラス名とか⼯工夫する
よりよいドメインモデルを探求するため。
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Groovyの柔軟性:日本語DSL
28
まず	
  100	
  の	
  平方根	
  を	
  表示する	
  
そして	
  1	
  と	
  2	
  と	
  3	
  のうち、	
  奇数	
  それぞれに	
  対して	
  {	
  それ	
  -­‐>	
  
	
  	
  二倍にした	
  それ	
  を	
  表示する	
  
}	
  
それはそれとして	
  "abc"	
  を	
  表示する	
  
ついでに	
  1	
  から	
  100	
  のうち、	
  二の倍数.かつ(三の倍数)	
  を	
  表示する	
  
最後に	
  1	
  から	
  100	
  のうち、	
  二の倍数.かつ(三の倍数)	
  それぞれに	
  対して	
  {	
  それ	
  -­‐>	
  
	
  	
  とりあえず	
  それ	
  +	
  "は6の倍数です"	
  を	
  表示する	
  
}	
  
//	
  10.0	
  
//	
  2,6	
  
//	
  "abc"	
  
//	
  [6,	
  12,	
  18,	
  24,	
  30,	
  36,	
  42,	
  48,	
  54,	
  60,	
  66,	
  72,	
  78,	
  84,	
  90,	
  96]
http://uehaj.hatenablog.com/entry/20100919/1284906117
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Groovyの柔軟性:リスト(モナド)内包表記
29
@Grab("org.jggug.kobo:groovy-­‐comprehension:0.3")	
  
import	
  groovyx.comprehension.keyword.select	
  
//	
  ピタゴラス数を求める	
  
assert	
  select	
  {	
  
	
  	
  	
  	
  a:	
  1..10	
  
	
  	
  	
  	
  b:	
  1..a	
  
	
  	
  	
  	
  c:	
  a..a+b	
  
	
  	
  	
  	
  a**2	
  +	
  b**2	
  ==	
  c**2	
  //	
  auto	
  guard	
  
	
  	
  	
  	
  yield("(a=$a,b=$b,c=$c)")	
  
}	
  ==	
  ["(a=4,b=3,c=5)",	
  "(a=8,b=6,c=10)"]	
  
https://github.com/uehaj/groovy-comprehension
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Groovyの柔軟性:型クラスもどき
30
interface	
  Monoid<T>	
  {	
  
	
  	
  	
  	
  def	
  T	
  mappend(T	
  t1,	
  T	
  t2);	
  
	
  	
  	
  	
  def	
  T	
  mempty();	
  
}	
  
import	
  static	
  Functions.*	
  
class	
  Functions	
  {	
  
	
  	
  static	
  <T>	
  T	
  mappend(T	
  t1,	
  T	
  t2,	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  Monoid<T>	
  dict=Parameter.IMPLICIT)	
  {	
  
	
  	
  	
  	
  dict.mappend(t1,t2)	
  }	
  
	
  	
  static	
  <T>	
  T	
  mempty(Monoid<T>	
  dict=Parameter.IMPLICIT)	
  {	
  
	
  	
  	
  	
  dict.mempty()	
  }	
  
}`	
  
def	
  instance_Monoid_java$lang$String_	
  =	
  new	
  Monoid<String>()	
  {	
  
	
  	
  	
  	
  @Override	
  String	
  mappend(String	
  i1,	
  String	
  i2)	
  {	
  i1+i2	
  }	
  
	
  	
  	
  	
  @Override	
  String	
  mempty()	
  {	
  ""	
  }	
  
}	
  
String	
  s	
  =	
  mempty()	
  
assert	
  s	
  ==	
  ""	
  
assert	
  mappend("a","b")	
  ==	
  "ab"}
https://github.com/uehaj/groovyz
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Groovyの柔軟性:LispBuilder
31
def	
  env	
  =	
  new	
  Env()	
  
env.eval{progn	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  ${defun;	
  average;	
  ${x;	
  y}	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ${div;	
  ${add;	
  x;	
  y};	
  $2}}	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  ${defun;	
  abs;	
  ${x}	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ${IF;	
  ${lt;	
  x;	
  $0};	
  ${mul;	
  x;	
  $(-­‐1)};	
  x}}	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  ${defun;	
  improve;	
  ${y;	
  x}	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ${average;	
  y;	
  ${div;	
  x;	
  y}}}	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  ${defun;	
  good_enoughp;	
  ${y;	
  x}	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ${le;	
  ${abs;	
  ${sub;	
  ${mul;	
  y;	
  y};	
  x}};	
  $(0.000001)}}	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  ${defun;	
  sqrt_iter;	
  ${y;	
  x}	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ${IF;	
  ${good_enoughp;	
  y;	
  x}	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  y	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ${sqrt_iter;	
  ${improve;	
  y;	
  x}	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  x}}}	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  ${defun;	
  sqrt;	
  ${x}	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ${sqrt_iter;	
  $(1.0);	
  x}}}	
  
assert	
  env.eval{sqrt;	
  $(3.0)}	
  ==	
  1.73205081
http://uehaj.hatenablog.com/entry/
20090706/1246836836
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
リアルワールドGroovy/Grails
Gradle: Androidの標準ビルドシステム

利用多数(「gradle」にマッチするgithubリポジトリ数
1701427)
Netflixでの大規模で多彩な活用
国内最大級オンラインマガジンサービスはGrails
New York Times

Getting Groovy With Reactive Android

(Android Groovy+RxJava)

http://open.blogs.nytimes.com/2014/08/18/getting-groovy-with-
reactive-android/
32
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
リアルワールドGrails
NTTソフトウェア株式会社では、GrailsをWebアプリ開発
の標準フレームワークとして位置付けています
33
特に投資・自社製品で活用
一般向け商用保守サービス
社内開発プロジェクトでのGrails/Groovy採用数推移
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.34
Javaプログラマの日
常の仕事をGroovyで
②Javaスクリ
プティング!
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Java開発のお供に(1)
キーが java ではじまるシステムプロパティを
一覧表示
groovysh(REPL)起動
もしくは
35
%	
  groovysh	
  
Groovy	
  Shell	
  (2.4.0-­‐beta-­‐4,	
  JVM:	
  1.8.0_25)	
  
Type	
  ':help'	
  or	
  ':h'	
  for	
  help.	
  
-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐
groovy:000>	
  System.properties.keySet().grep	
  
{	
  it.startsWith('java')	
  }	
  
===>	
  [java.runtime.name,	
  java.vm.version,	
  java.vm.vendor,	
  	
  …..	
  
%	
  groovy	
  -­‐e	
  "println	
  System.properties.keySet().grep	
  
{	
  it.startsWith('java')	
  }"
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Java開発のお供に(2)
GDKメソッド数をGroovyのドキュメントサイ
トからクラス別に集計する(Slide#15を作成)
36
Map	
  count	
  =	
  [:].withDefault{[]}	
  //集計用マップ	
  
new	
  URL("http://docs.groovy-­‐lang.org/latest/html/groovy-­‐jdk/
index-­‐all.html").text	
  
.eachMatch($/<b>(.*)</b></a>	
  -­‐	
  Method	
  in	
  [^	
  ]*	
  ([^<]*)<a	
  
[^>]*>([^<]*)/$)	
  {	
  g0,	
  k,	
  v1,	
  v2	
  -­‐>	
  
	
  	
  	
  	
  count[v1+v2]	
  <<	
  k	
  
}	
  
count.entrySet().sort{-­‐it.value.size()}.each	
  {	
  
	
  println	
  "${it.key}t${it.value.size()}"	
  
}	
  
println	
  "total="+count.entrySet().inject(0){total,item-­‐>total
+item.value.size()}	
  
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.37
今どきの
Groovy
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
最近(Groovy 2.3∼2.4)の機能追加
Groovy 最新版2.4.3(2015/4現在)
2.3
Traitの導入
マークアップテンプレートエンジン
型推論の改善
2.4
Android対応
イミュータブルソート・ユニーク
(Collection.{toSorted, toUnique})
38
http://uehaj.hatenablog.com/entry/2015/04/10/173816
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
Trait
「実装を持てるインターフェース」
Scalaのそれにごく近い
スタッカブルトレイト 、@SelfTypeアノテーション…
状態が持てる: Java8デフォルトメソッドとの違い
動的トレイト注入
プロキシオブジェクトを介するので、finalクラスにも注
入可
Grails 3で積極的に活用されている!
39
spring bootベースの軽量FWに
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
マークアップテンプレートエンジン
HTMLを簡潔なGroovyプログラムとして書け
るhamlっぽいテンプレート
40
html {
head { title タイトル" }
body {
h1 "タイトル"
ul {
(1..10).each {
li it
} } } }
<html>
<head>
<title>タイトル</title>
</head><body>
<h1>タイトル</h1><ul>
<li>1</li><li>2</li><li>3</
li><li>4</li><li>5</li><li>6</li><li>7</
li><li>8</li><li>9</li><li>10</li>
</ul>
</body>
</html>
Spring MVC 4のGroovyMarkupView、Grails/Groovyサ
イトを生成する静的サイトジェネレータで使用
機能: i18n/レイアウト/インクルード/型チェック
Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.
まとめ
GroovyはJava開発者の能力を高めるツール
用途:
Javaスクリプティング
DSL・ユビキタス言語
対象領域の問題に対して、最小完全な記述を求める

ことが本質。

そのための記法を追求
41

More Related Content

Shibuya JVM Groovy 20150418

  • 1. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.1 2015年 4月 18日 JGGUG/NTTソフトウェア株式会社 上原潤二 今さら始めよう Groovy 渋谷JVM
  • 2. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. わたくしは 上原潤二(@uehaj) NTTソフトウェア(株)Grails推進室 JGGUG運営委員 書籍: プログラミングGROOVY(技術評論社) Grails徹底入門(翔泳社) ブログ「Grな日々」 2 ElmとRust 推してます
  • 3. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. お品がき Groovyってどんな言語? Groovyの思想 Groovyはどう役立つのか? 今どきのGroovy 3
  • 4. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.4 Groovyって どんな言語?
  • 5. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Groovyってどんな言語?(1) 文法はJavaのほぼ上位互換 真のクロージャを持ち簡潔な記述を旨とする 型システム・型チェック Groovy 1.8までは実行時型チェックのみ、 Groovy 2.0からは静的型チェック・静的コンパイル →Javaに準じた静的なコードも吐ける 5
  • 6. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Groovyってどんな言語?(2) 実行 Groovy コードはJava バイトコード(クラス)に 常にコンパイルされて実行される ラッパーや特殊なコンテキストやインタプリタ無し ライブラリ 独自の体系はもたず、 Java 標準 API を基本と して Groovy 独自のクラスやメソッドを追加 6
  • 7. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.7 2003 2004 2005 2006 2007 2008 1.51.0 1.1 Groovy 1.0b4 JSR化 Groovy 1.0b10 JSR EA JSR-6 1.6-rc JSR化 2009 2010 2011 2012 2013 2014 2015 →G2One Groovy 1.7 Groovy 1.8 Groovy 2.0 Static Compilation Groovy 2.4 Android Support →SpringSource →VMWare →Pivotal 7月 Grails 0.3 Spock 0.1 Gradle 0.7 Grails 3.0 Groovyの歴史 JGGUG開始 AST変換 indy 今のGroovy基本 Groovy 2.5 Apache ASF
  • 8. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. 最近の話題 Pivotal社がスポンサーを降板(∼2015/3末) Groovy/Grailsコア開発メンバーの直接雇用終了 codehaus閉鎖もあり、GroovyはASF傘下の インキュベータープロジェクトに 8
  • 9. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. こんな感じのやりとり(想像です) 9 ぼくと契約して、ASF プロジェクトになって よ! きゅうべえ、いや (Apache)インキュベー ター!!!
  • 10. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Java7コード例(WordCount) 10 import  java.util.Comparator;    import  java.util.HashMap;    import  java.util.Map;    import  java.util.Set;    import  java.util.List;    import  java.util.ArrayList;    import  java.util.Collections;    import  java.io.FileReader;    import  java.io.BufferedReader;    import  java.io.IOException;        public  class  WordCount7  {      public  static  void  main(String[]  args)                throws  IOException  {        try  (FileReader  fis  =  new  FileReader(args[0]);              BufferedReader  br  =  new  BufferedReader(fis))  {          Map<String,  Integer>  map  =  new  HashMap<>();          String  line;          while  ((line  =  br.readLine())  !=  null)  {            for  (String  it:  line.split("W+"))  {              map.put(it,  (map.get(it)==null)  ?  1  :   (map.get(it)  +  1));            }          }          List<Map.Entry<String,  Integer>>  entrySetList              =  new  ArrayList<>(map.entrySet());          Comparator<Map.Entry<String,  Integer>>  comp  =            new  Comparator<Map.Entry<String,  Integer>>(){              public  int  compare(Map.Entry<String,  Integer>   o1,                              Map.Entry<String,  Integer>  o2)  {                return  o1.getValue()  -­‐  o2.getValue();              }            };          Collections.sort(entrySetList,  comp);          for  (Map.Entry<String,  Integer>  entry:   entrySetList)  {            System.out.println(entry.getValue()  +   ":"+entry.getKey());          }        }      }    }        System.out.println(entry.getValue()  +   ":"+entry.getKey());                }            }        }    }        def  words  =  new  File(args[0]).text.split(/W+/)    words.countBy{it}.entrySet().sort{it.value}.each  {        println  "${it.value}:  ${it.key}"    }   Groovyコード例(WordCount)
  • 11. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Java7コード例(Immutable) 11 public  final  class  Punter  {            private  final  String  first;            private  final  String  last;                public  Punter(String  first,  String  last)  {                    this.first  =  first;                    this.last  =  last;            }                public  String  getFirst()  {                    return  first;            }                public  String  getLast()  {                    return  last;            }                @Override            public  int  hashCode()  {                    final  int  prime  =  31;                    int  result  =  1;                    result  =  prime  *  result  +  ((first  ==  null)                            ?  0  :  first.hashCode());                    result  =  prime  *  result  +  ((last  ==  null)                            ?  0  :  last.hashCode());                    return  result;            }                @Override            public  boolean  equals(Object  obj)  {                    if  (this  ==  obj)                            return  true;                    if  (obj  ==  null)                            return  false;                    if  (getClass()  !=  obj.getClass())                            return  false;                    Punter  other  =  (Punter)  obj;                    if  (first  ==  null)  {                            if  (other.first  !=  null)                                    return  false;                    }  else  if  (!first.equals(other.first))                            return  false;                    if  (last  ==  null)  {                            if  (other.last  !=  null)                                    return  false;                    }  else  if  (!last.equals(other.last))                            return  false;                    return  true;            }                @Override            public  String  toString()  {                    return  "Punter(first:"  +  first                            +  ",  last:"  +  last  +  ")";            }    }    @Immutable  final  class  Punter  {            String  first,  last    } Groovyコード例(Immutable)
  • 12. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Groovyコードの実行 12 JVM 2011 Javaソース .classファイル javacコマンド javaコマンド 標準クラスローダ Javaクラス Groovyコード groovyコマンド Groovyクラスローダ (オンメモリ実行時コンパイラ) JavaクラスJavaクラス .classファイル groovycコマンド
  • 13. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Javaコードの実行 13 JVM Javaソース .classファイル javacコマンド javaコマンド 標準クラスローダ Javaクラス
  • 14. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Groovyコードの実行 146 JVM 標準クラスローダ Groovyコード groovyコマンド Groovyクラスローダ (オンメモリ実行時コンパイラ) JavaクラスJavaクラス .classファイル groovycコマンド
  • 15. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. GDK Groovyのために拡張されたJava API Collection#each(), Iterator#groupBy().. File#getText(), File#renameTo()… String#execute(), String#tr(), .. 15 "ls".execute()  'こんにちは'.tr('あ-ん', ‘ア-ン')  new File("tmp.txt") << "hellon"
  • 16. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. GDKメソッド群 16 クラス GDK追加メソッド数 java.lang.CharSequenc 93 java.io.File 88 java.nio.file.Path 86 java.lang.Iterable 84 java.lang.Object 77 java.util.List 72 java.lang.Object[] 63 java.util.Map 58 java.util.Iterator 54 java.util.Collection 48 : : Total 1352
  • 17. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.17 Groovyの 思想
  • 18. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Groovyの設計思想 「Javaを置き換えない」 Javaとの併用・共存・補完が存在意義そのもの。 GroovyはJavaクラスファイルを別ルート・別記法で読み 込ませるためのクラスローダーであり、ライブラリの一種 でもある。 JavaのAPIやライブラリはGroovyにとって必要悪で はない。 Javaライブラリは直接もしくは、Groovyラッピング・ 拡張し使用 RxGroovy/RxJava, .. 18
  • 19. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. JRuby想定ユーザタイプ別Groovy乗り換えガイド JRuby想定ユーザA: しょうがなくJVMを使う 必要にせまられたrubiest。 JRuby想定ユーザB: Java APIもJVMも大好き だがJavaの文法だけは嫌 い。 JRuby想定ユーザC: RubyのライブラリをJVM 上で使いたいだけの人 Java APIはなるべく呼びませ ん。Javaは必要悪! Groovyとの競合の余地ゼロ。 Groovyと思いきり競合 あなたはGroovyを使えばもっ と幸せになれるかも。 Groovyとの競合の余地ゼ ロ。
  • 20. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.20 Groovyはど う役立つのか?
  • 21. Grails, Gradle、Spock など、DSLを実装するツー ルやFWを通じて利用 Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Groovyの主な用途2つ 21 ①DSLを実装 するための言語 ②Javaスクリ プティング! Javaプログラマの日 常の仕事をGroovyで
  • 22. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.22 Grails, Gradle、Spock など、DSLを実装するツー ルやFWを通じて利用 ①DSLを実装 するための言語
  • 23. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. ファクト: DSL実装言語としてのGroovy Spock Gradle Grails Geb Jenkins MarkupTemplateEngine/MarkupBuilder 23 テストコード記述用DSL Webアプリ記述用DSL ビルド手順記述用DSL Selenium2制御用DSL HTML代替DSL ワークフロー定義DSL、CLI
  • 24. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Spockによるテストコード 24 パラメータのバリエーションを表形式で記 述(|はビットOR演算子) 表の1行がそれぞれ別のテストケース(テ ストメソッド)として実行されたかのように結 果が表示される。
  • 25. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Why Groovy DSL? Groovy「Java開発者向けのDSL」に最適 Groovyのシンタックスやセマンティクスが「優れて いる」必要はない Java開発者にとって素直にわかればよく、
 意表をつく何かが無い方が良い 加えて、 「中括弧言語」としての十分な表現力 高速コンパイル、トライアンドエラーのしやすさ 動的型 25
  • 26. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. 動的型とDSL 「本質的に動的」な対象のDSLモデリングには、
 動的型が自然な記述に寄与 26  def  slurper  =  new  JsonSlurper()    def  result  =   slurper.parseText('{"person": {"name":"Guillaume","age":33,"pets": ["dog","cat"]}}')    assert  result.person.name  ==   "Guillaume"    assert  result.person.age  ==  33    assert  result.person.pets.size()  ==  2    assert  result.person.pets[0]  ==  "dog"    assert  result.person.pets[1]  ==  "cat"   html  {        head  {              meta(charset:'utf-­‐8')              title('Page  title')        }   } JSONを対象とした処理 HTMLマークアップ
  • 27. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Why DSL? 27 加えて、実装⾔言語の都合(⽂文 法・意味)をただ受け⼊入れるの ではなく、
 あるべき記法を追求する ドメインモデルを書き下 すのに、既存⾔言語の⽂文法 や実装都合の範囲内で、 クラス名とか⼯工夫する よりよいドメインモデルを探求するため。
  • 28. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Groovyの柔軟性:日本語DSL 28 まず  100  の  平方根  を  表示する   そして  1  と  2  と  3  のうち、  奇数  それぞれに  対して  {  それ  -­‐>      二倍にした  それ  を  表示する   }   それはそれとして  "abc"  を  表示する   ついでに  1  から  100  のうち、  二の倍数.かつ(三の倍数)  を  表示する   最後に  1  から  100  のうち、  二の倍数.かつ(三の倍数)  それぞれに  対して  {  それ  -­‐>      とりあえず  それ  +  "は6の倍数です"  を  表示する   }   //  10.0   //  2,6   //  "abc"   //  [6,  12,  18,  24,  30,  36,  42,  48,  54,  60,  66,  72,  78,  84,  90,  96] http://uehaj.hatenablog.com/entry/20100919/1284906117
  • 29. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Groovyの柔軟性:リスト(モナド)内包表記 29 @Grab("org.jggug.kobo:groovy-­‐comprehension:0.3")   import  groovyx.comprehension.keyword.select   //  ピタゴラス数を求める   assert  select  {          a:  1..10          b:  1..a          c:  a..a+b          a**2  +  b**2  ==  c**2  //  auto  guard          yield("(a=$a,b=$b,c=$c)")   }  ==  ["(a=4,b=3,c=5)",  "(a=8,b=6,c=10)"]   https://github.com/uehaj/groovy-comprehension
  • 30. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Groovyの柔軟性:型クラスもどき 30 interface  Monoid<T>  {          def  T  mappend(T  t1,  T  t2);          def  T  mempty();   }   import  static  Functions.*   class  Functions  {      static  <T>  T  mappend(T  t1,  T  t2,                                                Monoid<T>  dict=Parameter.IMPLICIT)  {          dict.mappend(t1,t2)  }      static  <T>  T  mempty(Monoid<T>  dict=Parameter.IMPLICIT)  {          dict.mempty()  }   }`   def  instance_Monoid_java$lang$String_  =  new  Monoid<String>()  {          @Override  String  mappend(String  i1,  String  i2)  {  i1+i2  }          @Override  String  mempty()  {  ""  }   }   String  s  =  mempty()   assert  s  ==  ""   assert  mappend("a","b")  ==  "ab"} https://github.com/uehaj/groovyz
  • 31. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Groovyの柔軟性:LispBuilder 31 def  env  =  new  Env()   env.eval{progn                    ${defun;  average;  ${x;  y}                        ${div;  ${add;  x;  y};  $2}}                    ${defun;  abs;  ${x}                        ${IF;  ${lt;  x;  $0};  ${mul;  x;  $(-­‐1)};  x}}                    ${defun;  improve;  ${y;  x}                        ${average;  y;  ${div;  x;  y}}}                    ${defun;  good_enoughp;  ${y;  x}                        ${le;  ${abs;  ${sub;  ${mul;  y;  y};  x}};  $(0.000001)}}                    ${defun;  sqrt_iter;  ${y;  x}                        ${IF;  ${good_enoughp;  y;  x}                            y                            ${sqrt_iter;  ${improve;  y;  x}                                x}}}                    ${defun;  sqrt;  ${x}                        ${sqrt_iter;  $(1.0);  x}}}   assert  env.eval{sqrt;  $(3.0)}  ==  1.73205081 http://uehaj.hatenablog.com/entry/ 20090706/1246836836
  • 32. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. リアルワールドGroovy/Grails Gradle: Androidの標準ビルドシステム
 利用多数(「gradle」にマッチするgithubリポジトリ数 1701427) Netflixでの大規模で多彩な活用 国内最大級オンラインマガジンサービスはGrails New York Times
 Getting Groovy With Reactive Android
 (Android Groovy+RxJava)
 http://open.blogs.nytimes.com/2014/08/18/getting-groovy-with- reactive-android/ 32
  • 33. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. リアルワールドGrails NTTソフトウェア株式会社では、GrailsをWebアプリ開発 の標準フレームワークとして位置付けています 33 特に投資・自社製品で活用 一般向け商用保守サービス 社内開発プロジェクトでのGrails/Groovy採用数推移
  • 34. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.34 Javaプログラマの日 常の仕事をGroovyで ②Javaスクリ プティング!
  • 35. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Java開発のお供に(1) キーが java ではじまるシステムプロパティを 一覧表示 groovysh(REPL)起動 もしくは 35 %  groovysh   Groovy  Shell  (2.4.0-­‐beta-­‐4,  JVM:  1.8.0_25)   Type  ':help'  or  ':h'  for  help.   -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ groovy:000>  System.properties.keySet().grep   {  it.startsWith('java')  }   ===>  [java.runtime.name,  java.vm.version,  java.vm.vendor,    …..   %  groovy  -­‐e  "println  System.properties.keySet().grep   {  it.startsWith('java')  }"
  • 36. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Java開発のお供に(2) GDKメソッド数をGroovyのドキュメントサイ トからクラス別に集計する(Slide#15を作成) 36 Map  count  =  [:].withDefault{[]}  //集計用マップ   new  URL("http://docs.groovy-­‐lang.org/latest/html/groovy-­‐jdk/ index-­‐all.html").text   .eachMatch($/<b>(.*)</b></a>  -­‐  Method  in  [^  ]*  ([^<]*)<a   [^>]*>([^<]*)/$)  {  g0,  k,  v1,  v2  -­‐>          count[v1+v2]  <<  k   }   count.entrySet().sort{-­‐it.value.size()}.each  {    println  "${it.key}t${it.value.size()}"   }   println  "total="+count.entrySet().inject(0){total,item-­‐>total +item.value.size()}  
  • 37. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved.37 今どきの Groovy
  • 38. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. 最近(Groovy 2.3∼2.4)の機能追加 Groovy 最新版2.4.3(2015/4現在) 2.3 Traitの導入 マークアップテンプレートエンジン 型推論の改善 2.4 Android対応 イミュータブルソート・ユニーク (Collection.{toSorted, toUnique}) 38 http://uehaj.hatenablog.com/entry/2015/04/10/173816
  • 39. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. Trait 「実装を持てるインターフェース」 Scalaのそれにごく近い スタッカブルトレイト 、@SelfTypeアノテーション… 状態が持てる: Java8デフォルトメソッドとの違い 動的トレイト注入 プロキシオブジェクトを介するので、finalクラスにも注 入可 Grails 3で積極的に活用されている! 39 spring bootベースの軽量FWに
  • 40. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. マークアップテンプレートエンジン HTMLを簡潔なGroovyプログラムとして書け るhamlっぽいテンプレート 40 html { head { title タイトル" } body { h1 "タイトル" ul { (1..10).each { li it } } } } <html> <head> <title>タイトル</title> </head><body> <h1>タイトル</h1><ul> <li>1</li><li>2</li><li>3</ li><li>4</li><li>5</li><li>6</li><li>7</ li><li>8</li><li>9</li><li>10</li> </ul> </body> </html> Spring MVC 4のGroovyMarkupView、Grails/Groovyサ イトを生成する静的サイトジェネレータで使用 機能: i18n/レイアウト/インクルード/型チェック
  • 41. Slide # 渋谷JVM Copyright(C) 2015 NTT Software Corporation All rights reserved. まとめ GroovyはJava開発者の能力を高めるツール 用途: Javaスクリプティング DSL・ユビキタス言語 対象領域の問題に対して、最小完全な記述を求める
 ことが本質。
 そのための記法を追求 41