28
summer special g* workshop / 2009.08.22 slide #1 お題でGroovyプログラミング

お題でGroovyプログラミング: Part A

Embed Size (px)

DESCRIPTION

JGGUGサマースペシャルg*ワークショップ2009での発表資料。Part Bは上原さん、Part Cは須江さん。

Citation preview

Page 1: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #1

お題でGroovyプログラミング

Page 2: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #2

このセッションのねらい! 具体的かつ実践的な、短い「お題」を使ってGroovyの特徴や便利さを伝えたい

! 一方的な解説ではなく、みんなで一緒に考えることで理解を深めたい

プレゼントもあるよ!

Page 3: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #3

進め方! 「お題」とヒント・注意点の説明

http://groups.google.com/group/jggug-summer-2009

! プログラミング・タイム! できた人はコードを次のアドレスにポスト[email protected]

subjectにお題番号と回答者の名前/ハンドルを書いてください! 回答者からの発表

! 解答例とポイントの解説 質問はいつでもお気軽に

Page 4: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #4

アジェンダ! Part A ‒ 関谷

! ファイル処理、フィードリーダー、簡易サーバ! Part B ‒ 上原

! 正規表現、JDKへのメソッド追加、Twitter! Part C ‒ 須江

! Swing、XML編集

Page 5: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #5

準備! Java 5以降およびGroovy 1.6.xがインストールされていること

! 環境変数JAVA_HOMEおよびGROOVY_HOMEが設定されていること

! $GROOVY_HOME/binにパスが通っていること

! 確認方法% groovy -vGroovy Version: 1.6.4 JVM: 1.5.0_19

Page 6: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #6

Groovyとは(1分で)! Java VM上で動作する動的スクリプト言語

! JSR-241で標準化。実装はオープンソース! 特徴

! 簡潔さ– RubyなどのLLと同水準の強力な表現力

! 柔軟性– 動的、メタプログラミング、DSL向き

! Javaとの親和性– 構文、相互呼び出し、実行環境、知識/ノウハウ

Page 7: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #7

Part Aコーディネータ:関谷

Page 8: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #8

お題 A-1: ファイルコピー! 指定したファイルを指定した名前にコピーするスクリプトを書いてください! Input/OutputStream や Reader/Writer を使わずにやってみましょう

% groovy filecopy <srcfile> <destfile>

Page 9: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #9

お題 A-1: ヒントと注意点! コマンドライン引数は args[0], args[1]! いろいろな方法があります

! GDKでFileクラスに追加されたメソッドを活用! 外部コマンドを起動! Antタスクを利用! ベストな方法は?

groovy.util.AntBuilder

File#getText(), readBytes(), append(), leftShift()...

String#execute()

Page 10: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #10

解答例 A-1a

src = new File(args[0])dest = new File(args[1])dest << src.text

普通のjava.io.Fileクラス

dest.leftShift(src.getText()) と等価leftShiftはappendを呼び出すいずれもGDKにより追加されたメソッド

バイナリファイルに対しては正しく動作しない!

Page 11: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #11

解答例 A-1b

src = new File(args[0])dest = new File(args[1])dest << src.readBytes()

巨大なファイルではOutOfMemoryErrorが発生!

Page 12: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #12

解答例 A-1c

proc = "cp ${args[0]} ${args[1]}".execute()proc.waitFor()

waitFor() はなくても動くが、cpの完了を待たずにスクリプトが終了してしまう

巨大なファイルでもOKだが、UNIXのcpコマンドに依存

Page 13: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #13

解答例 A-1d

ant = new AntBuilder()ant.copy(file:args[0], tofile:args[1])

ベストな解?テキストでもバイナリでもOK巨大なファイルにも対応し、プラットフォーム非依存

Antのcopyタスク

Page 14: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #14

お題 A-2: フィードリーダー! 指定したURLからフィードを読み込み、ヘッドライン(全item/entryのtitle)を出力するスクリプトを書いてください

! できれば、RSS 1.0/2.0、Atom等、多様なフィードフォーマットに対応できるようにしてみてください% groovy feedreader <URL>

Page 15: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #15

お題 A-2: ヒントと注意点! フィードの取得と解析は XmlParser または xmlSlurper の parse(String url) が便利

! フィード要素へのアクセスはGPath記法で

Page 16: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #16

RSS 0.9/1.0の基本構造<rdf:RDF> <channel> ... </channel> <item> <title>...</title> ... </item> <item> <title>...</title> ... </item></rdf:RDF>

Page 17: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #17

RSS 0.9x/2.0の基本構造<rss> <channel> ... <item> <title>...</title> ... </item> <item> <title>...</title> ... </item> </channel></rss>

Page 18: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #18

Atomの基本構造<feed> ... <entry> <title>...</title> ... </entry> <entry> <title>...</title> ... </entry></feed>

Page 19: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #19

解答例 A-2root = new XmlSlurper().parse(args[0])switch(root.name()) { case 'RDF' : nodes = root.item; break case 'rss' : nodes = root.channel.item; break case 'feed': nodes = root.entry; break}nodes.each { println it.title }

Page 20: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #20

お題 A-3: 簡易webサーバ! ブラウザからのリクエストに対して、常に固定HTMLファイルを返すHTTPサーバを書いてください! groovyコマンドの -l (listen)オプションを使ってください

% groovy -l 8080 httpserver

Page 21: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #21

お題 A-3: ヒントと注意点! -l <port> オプションの働き

! 指定したポートでクライアントからの接続を待ち受ける

! 接続があったら、クライアントから送られて来るデータを行単位で変数lineにセットしつつ、スクリプトをループ実行する

! 一つの接続に対するループを終了するには return 'success' を実行する

Page 22: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #22

解答例 A-3if (!line) { println 'HTTP/1.0 200 OK' println 'Content-Type: text/html\n' println new File('message.html').text return 'success'}

If 文はなくても動くが、動作の理解や将来の拡張のためにはあった方が良いかも

Page 23: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #23

お題 A-3改: 簡易webサーバ! 固定HTMLファイルの中に、<% … %> や <%= … %> などを使って任意のGroovy式を埋め込めるようにサーバを拡張してください

% groovy -l 8080 httpserver

Page 24: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #24

お題 A-3改: ヒントと注意点! groovy.text.SimpleTemplateEngineを利用

! importが必要な上、名前が長いので import as を使って別名をつけると良い

Page 25: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #25

解答例 A-3改import groovy.text.SimpleTemplateEngine as STE

if (!line) { println 'HTTP/1.0 200 OK' println 'Content-Type: text/html\n' text = new File('message.html').text println new STE().createTemplate(text).make() return 'success'}

Page 26: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #26

お題 A-4: オプション解析! コマンドラインオプションを解析するスクリプトを書いてください(どう書く?orgより )! cmdopt -o [-q] -d{0|1|2} 文字列 [文字列 …]! 詳細は http://ja.doukaku.org/205/

% groovy cmdopt <arguments...>

Page 27: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #27

解答例 A-4cli = new CliBuilder(usage:'cmdopt -o [-q] [-d{0|1|2}] 文字列 [文字列 ...]')cli.with { o longOpt:'output', 'set output', required:true q longOpt:'quote', 'set quote' d longOpt:'debug', 'set debug level', args:1, argName:'level'}

if (!(opt = cli.parse(args))) die 'bad command line'params = opt.arguments()if (params.size() < 1) die 'parameter must be specified'level = opt.d ? opt.d as int : 0if (!(level in 0..2)) die 'debug level must be in 0-2'

<次ページへ続く>

Page 28: お題でGroovyプログラミング: Part A

summer special g* workshop / 2009.08.22slide #28

解答例 A-4

println '[オプション情報]'println "o(output): ${opt.o ? 'ON' : 'OFF'}"println "q(quote): ${opt.q ? 'ON' : 'OFF'}"println "d(debug): $level"println '\n[パラメータ情報]'println "指定数: ${params.size()}"params.eachWithIndex { param, i -> println "${i + 1}: $param" }

def die(msg) { cli.writer.println "error: $msg" cli.usage() System.exit 1}

<前ページからの続き>