Upload
takahiro-sugiura
View
399
Download
0
Embed Size (px)
DESCRIPTION
Citation preview
Closures and methodMissing
are realG* ワークショップ Z 札幌 2014
2014/09/27
日本語で言うと
クロージャも、methodMissingも、あるんだよG* ワークショップ Z 札幌 2014
2014/09/27
背景を付けると、
クロージャも、methodMissingも、あるんだよG* ワークショップ Z 札幌 2014
2014/09/27
お前誰よ
• 名前:杉浦孝博 • twitter : @touchez_du_bois • 夜のお仕事: 深夜アニメ普及活動 提督業(艦隊これくしょん)
It's not important,
but... (余談ですが)
Do you know the DSL?
(DSLをご存じですか?)
DSL• Domain Specific Languageの略。 • 特定の領域(ドメイン)の問題を解決するための言語。 • 専用のパーサーを作る「外部DSL」と、プログラミング言語を利用する「内部DSL」、といった分け方ができる。
内部DSLの例• GrailsでSpring Beanの登録。
// grails-app/conf/spring/resources.groovy !import my.company.MyBeanImpl !beans = { myBean(MyBeanImpl) { someProperty = 42 otherProperty = "blue" } }
GroovyでDSL• Builder • Category • Operator overloading • Command chains • Closure • Meta programming • AST Transformer ...
Let’s make a DSL!
(DSLを作ってみよう!)
お題• VoiceText Web API (β版) • https://cloud.voicetext.jp/webapi • 音声合成VoiceTextを簡単に使うことができるWeb API • このWeb APIを叩くためのDSLを作ってみる。
お題• こんな感じのAPI
curl "https://api.voicetext.jp/v1/tts" \ -o "test.wav" \ -u "YOUR_API_KEY:" \ -d "text=おはようございます" \ -d "speaker=hikari"
お題• パラメータ
text合成するテキスト。エンコーディングはUTF-8。Unicodeで200文字以内。
speaker 話者名
emotion 感情カテゴリ
emotion_level 感情レベル
pitch 音の高低
speed 話す速度
volume 音量
VoiceText4J• @makingさん作のJava版ライブラリ • https://github.com/making/voicetext4j/ • 大いに参考にさせていただきました。
VoiceText4J
import am.ik.voicetext4j.*; !System.setProperty("voicetext.apikey", “API_KEY"); !EmotionalSpeaker.HIKARI.ready() .pitch(105) .speed(105) .speak("おはようございます");
I made a DSL.
(DSLを作ってみた)
こんな感じimport org.jggug.magica.voicetext4g.VoiceTextFactory import org.jggug.magica.voicetext4g.config.Speaker !def voiceText = VoiceTextFactory.create("YOUR_API_KEY") !voiceText.speak { speaker Speaker.HIKARI pitch 105 speed 105 "おはようございます" }
Demo. (でも)
デモのソースimport org.jggug.magica.voicetext4g.VoiceTextFactory import org.jggug.magica.voicetext4g.config.Speaker !def voiceText = VoiceTextFactory.create("YOUR_API_KEY") !voiceText.speak { speaker Speaker.SHOW "どうも、奥さん、知ってるでしょ〜、大泉洋でございます。おい、パイ食わねえか?" }
Points (ポイント)
クロージャを使うvoiceText .speaker(Speaker.HIKARI) .pitch(105) .speed(105) .speak("おはようございます") ! ↓ !voiceText.speak { speaker Speaker.HIKARI pitch 105 speed 105 "おはようございます" }
メソッド呼び出しのカッコ省略voiceText.speak( { speaker(Speaker.HIKARI) pitch(105) speed(105) "おはようございます" }) ! ↓ !voiceText.speak { speaker Speaker.HIKARI pitch 105 speed 105 "おはようございます" }
return 省略voiceText.speak { speaker Speaker.HIKARI pitch 105 speed 105 return "おはようございます" } ! ↓ !voiceText.speak { speaker Speaker.HIKARI pitch 105 speed 105 "おはようございます" }
クロージャの戻り値def speak(Closure c) { def text = c() // クロージャの戻り値の型がStringかGString以外の場合、 // 何もしない if (!(text instanceof String || text instanceof GString)) { return } ! // Web APIを叩き、音声を再生 }
設定用のメソッド
class VoiceText { Config config def speak(Closure c) { } }
• VoiceTextクラスに、speakerやpitch等の設定用メソッドは定義しない。 • 設定用のクラス(Config)のオブジェクトをメンバ変数に持つ。
delegateを変更class VoiceText { Config config def speak(Closure c) { c.delegate = this def text = c() } }
methodMissingclass VoiceText { Config config def speak(Closure c) { c.delegate = this def text = c() } def methodMissing(String name, args) { config."${name}" = args[0] } }
To wrap up (まとめ)
まとめ• クロージャやmethodMissingなどを使うことで、自分だけのDSL(DSLっぽいもの)が作れる。 • オレオレDSLで差を付けよう!
Get back on topic (閑話休題)
2014 秋アニメ オススメ
PSYCHO-PASS 2
棺のチャイカ 第2期
AVENGING BATTLE
selector spread WIXOSS
蟲師 続章
ご清聴 ありがとう
ございました。