Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
面倒なことはScalaスクリプトにやらせよう / let scala scripts do t...
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Takumi Kadowaki
September 16, 2019
Programming
1.2k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
面倒なことはScalaスクリプトにやらせよう / let scala scripts do the troublesome things
2019/09/13 Scala秋祭り
Takumi Kadowaki
September 16, 2019
More Decks by Takumi Kadowaki
See All by Takumi Kadowaki
Datadog Error Tracking & Claude Code Action で アプリケーションエラーを(半)自動修正 / Datadog Error Tracking & Claude Code Action (semi-)auto-correct application errors
nomadblacky
1
150
Reckoner における Datadog Browser Test の活用事例 / Datadog Browser Test at Reckoner
nomadblacky
0
600
Scala アプリケーションのビルドを改善してデプロイ時間を 1/4 にした話 | How I improved the build of my Scala application and reduced deployment time by 4x
nomadblacky
1
1.4k
Reckoner の Scala プロジェクトにおける オブザーバビリティの取り組み / Observability Initiatives in Reckoner's Scala Project
nomadblacky
0
2.8k
AWS CDK on Scala ~ Scalaでインフラ管理してみたはなし / Manage infrastructure with AWS CDK on Scala
nomadblacky
0
4.8k
Slinky で Scala.js 製 React Webアプリケーションを つくったはなし / How to build a Scala.js React web application in Slinky
nomadblacky
1
5.4k
Other Decks in Programming
See All in Programming
スマートフォンでモールス信号を送受信する 〜スマートフォンのLEDとカメラで作る光通信の設計と実装〜
atsuki_seo
0
150
wkhtmltopdfの次どうするか問題2026
willnet
2
1.5k
WebRTC映像をAirPlayに対応させる挑戦.pdf
monolithic_adam
0
290
一人だけ、Kiroが静止する日
hideg
0
120
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
220
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
350
モジュールの視点からSwiftを読み解く #iosdc
s_shimotori
0
180
速習iPhone Duo対応
yuukiw00w
1
660
手動確認はもう限界 〜XCUITestでCustom URL Schemeの遷移を起動種別ごとに自動テストする〜 / Testing Custom URL Schemes with XCUITest
otouto
0
310
iOSDC2026登壇資料.pdf
riofujimon
0
170
WebMCP Challenge に星空観察アプリで参加した話
okajun35
0
180
What We Talk About When We Talk About XP
m_seki
2
660
Featured
See All Featured
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
240
Raft: Consensus for Rubyists
vanstee
142
7.7k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.6k
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
320
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.8k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
890
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
5
700
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.4k
Ethics towards AI in product and experience design
skipperchong
2
380
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
280
Into the Great Unknown - MozCon
thekraken
41
2.7k
Transcript
面倒なことは Scalaスクリプトにやらせよう 2019/09/16 Scala秋祭り Takumi Kadowaki @blac_k_ey
どなた? Takumi Kadowaki Twitter: @blac_k_ey GitHub: NomadBlacky セプテーニ・オリジナル PYXISチーム所属 広告運用自動化ツールのバックエンド開発が主な仕事
海と温泉とテトリスが好き ScalaMatsuri2019で頒布した「技術読本」に 「ServerlessFramework + Scala」なアプリケーションについて記事を書き ました
突然ですが問題です
DockerHubからあるイメージのタグ一覧をAPIから取得して、 最もサイズの小さいものと大きいものを出力してください { "count": 257, "page": 1, "page_size": 25, "results":
[ { "id": 2255500, "name": "stable", "last_updated": "2019-09-12T14:51:49.113501Z", "full_size": 50665062 }, { "id": 19451, "name": "latest", "last_updated": "2019-09-12T14:51:29.159817Z", "full_size": 50665667 }, ... ] } https://hub.docker.com/api/content/v1/repositories/public/library/nginx/tags
シェルスクリプトで複雑なことをするとつらい… $ curl \ https://hub.docker.com/api/.../nginx/tags \ | jq .results[].full_size ...
(ここで考えるのをやめる) (我々は jq コマンドのプロではない…) (ページングとか考えるとさらにめんどい…) とりあえずシェルスクリプトで…
みんな大好きScala! みんな大好きsbt!
小さいプログラムを書くにはオーバー… • build.sbt ◦ ビルド定義 ◦ 依存解決 • build.properties ◦
sbtバージョンの指定 ◦ プラグイン (sbt-assembly etc.) • src/main/scala/.../Hoge.scala ◦ 目的のコード
世の中には色々なスクリプト言語がある JavaScript Ruby Python Groovy PHP Perl etc...
それでもやっぱりScalaで書きたい〜 JavaScript Ruby Python Groovy PHP Perl
この間を埋めるものはないだろうか… コード量/プロジェクト規模 大 小 Shell Script
そんなあなたに、 Ammonite 大 小 @ コード量/プロジェクト規模 Shell Script
Ammoniteとは? https://ammonite.io lihaoyi/Ammonite • Scala REPL • Script Runner •
File System Library • Shell これらの総称
Ammonite-REPL
http://ammonite.io/#Ammonite-REPL 何はともあれ、まずはインストールしてみよう (Linuxなど ※執筆時の最新版) $ sudo sh -c '(echo "#!/usr/bin/env
sh" && curl -L https://github.com/lihaoyi/Ammonite/releases/download/1.6.9/2.13-1.6.9) > /usr/local/bin/amm && chmod +x /usr/local/bin/amm' && amm コマンドをひとつ実行するだけ! (Macのかた) $ brew install ammonite-repl
Hello World!!
Ammonite-REPLの便利な機能 • シンタックスハイライト • 複数行のコード編集 • Undo & Redo •
Magic Import • browse ◦ 大きな配列など、文字列表現が長い評価結果をページャで確認 • source ◦ REPL上でソースコードを閲覧
Magic Import Maven Central からJarを取得して、すぐにライブラリを使える! import $ivy.`<group_id>::<artifact_id>:<version>` // cats の例
import $ivy.`org.typelevel::cats-core:2.0.0` // sbt との比較 libraryDependencies += "org.typelevel" %% "cats-core" % "2.0.0"
None
Ammonite-Script
Scalaコードをコマンドラインから直接コンパイル・実行! sample.sc println("Hello Ammonite!!")
Scalaコードをコマンドラインから直接コンパイル・実行! sample.sc println("Hello Ammonite!!") Scalaスクリプトでよく使われる拡張子
Scalaコードをコマンドラインから直接コンパイル・実行! sample.sc println("Hello Ammonite!!") $ amm sample.sc amm コマンドの後ろにスクリプトのパ ス
Scalaコードをコマンドラインから直接コンパイル・実行! sample.sc println("Hello Ammonite!!") $ amm sample.sc Compiling (synthetic)/ammonite/predef/DefaultPredef.sc Compiling
/home/blacky/sample.sc Hello Ammonite!! その場でコンパイル &実行!
Scalaコードをコマンドラインから直接コンパイル・実行! sample.sc println("Hello Ammonite!!") $ amm sample.sc Compiling (synthetic)/ammonite/predef/DefaultPredef.sc Compiling
/home/blacky/sample.sc Hello Ammonite!! $ amm sample.sc Hello Ammonite!! 2回目以降はコンパイルしないので実行が早い !
Magic Importとの合わせ技 sample_magic.sc import $ivy.`org.jsoup:jsoup:1.12.1` val doc = org.jsoup.Jsoup.connect("https://www.google.com").get println(doc.getElementsByTag("title"))
$ amm sample_magic.sc <title>Google</title> もちろんスクリプトでも Magic Importが使える!
Ammoniteに含まれるライブラリ依存
デフォルトで使える便利なライブラリたち Ammoniteに含まれている依存はMagicImportをせずとも使えます。 その中でもスクリプトの実装に役立つライブラリを一部紹介します。 $ coursier resolve com.lihaoyi:ammonite_2.13.0:1.6.9 ... com.lihaoyi:ammonite-ops_2.13:1.6.9:default com.lihaoyi:os-lib_2.13:0.3.0:default
com.lihaoyi:requests_2.13:0.2.0:default com.lihaoyi:upickle_2.13:0.7.5:default ... ...
デフォルトで使える便利なライブラリたち • ammonite-ops / os-lib ◦ https://github.com/lihaoyi/os-lib ◦ ファイル操作、サブプロセス実行などを提供 •
requests ◦ https://github.com/lihaoyi/requests-scala ◦ HTTPクライアント • upickle ◦ https://github.com/lihaoyi/upickle ◦ シリアライゼーションライブラリ ◦ MsgPack / JSON に対応
実際の活用例
esa.ioの利用状況をDatadogで可視化してみる Stats取得 メトリクス送信 GitLab CI の Scheduled Jobで 1時間に1回実行
ソースコード スライドには収まりきらなかったのでgistで… https://gist.github.com/NomadBlacky/2c56814a1993e327ed2c2e3d 8da01eed
GitLab CI での実行ログ ./amm esa-stats-to-datadog.sc --team septeni-original Get septeni-original.esa.io stats
... { "members": 55, "posts": 298, "posts_wip": 51, "posts_shipped": 247, "comments": 157, "stars": 197, "daily_active_users": 1, "weekly_active_users": 13, "monthly_active_users": 26 } Post stats to Datadog ... Done!
あとはダッシュボードを作ってあげるだけ
Scala製のDatadog APIクライアントを作りました! Starください!!! https://github.com/NomadBlacky/scaladog (宣伝)
そのほか… • Twitterの「いいね」から画像を取得する ◦ https://github.com/NomadBlacky/ammonite-scripts/blob/master/bin/get-twitter-images.sc • 何度閉じてもダイアログが出てくるScalaスクリプト ◦ https://gist.github.com/NomadBlacky/a70d76f5d699994da83c92775935f3f6 ◦
実行は自己責任でお願いします • ScalaからAWS CDKを叩いてインフラを構築する ◦ http://nomadblacky.hatenablog.com/entry/2019/07/14/194607 ◦ Scalaでインフラを作る!
おわりに
参考資料 • Document ◦ http://ammonite.io/ • GitHub ◦ https://github.com/lihaoyi/ammonite •
Blog ◦ http://www.lihaoyi.com • Video ◦ https://vimeo.com/148552858 • IntelliJ IDEA + AmmoniteでScalaスクリプトの開発を始めよう ◦ 弊社エンジニアブログ ◦ http://labs.septeni.co.jp/entry/2018/12/20/120000
まとめ • 便利なREPLとしてのAmmonite ◦ ちょっとScalaを書いて試したい時にAmmoniteを! ◦ 特に「Magic Import」が便利! • ScalaスクリプトとしてのAmmonite
◦ シェルスクリプトだと面倒、sbtだとオーバーという時の選択肢に! ◦ ざっくり書いてもコンパイラが怒ってくれる ▪ (ちょっとしたテスト代わり) ◦ Java/Scalaの資産が使える! ◦ 何よりScalaでスクリプトを書ける!! ▪ 楽しい!!!!
ちなみに: 最初の問題の回答 import upickle.default._ case class Response(page: Int, page_size: Int,
results: Seq[Tag]) case class Tag(name: String, full_size: Long) implicit val responseReader: Reader[Response] = macroR implicit val tagReader: Reader[Tag] = macroR def fetchAllTags(image: String): Seq[Tag] = Stream.from(1).map { page => read[Response]( requests.get( url = s"https://hub.docker.com/api/content/v1/repositories/public/library/$image/tags", params = Map("page" -> page.toString) ).text ) }.takeWhile(r => r.page < r.page_size) .flatMap(_.results) @main def main(image: String): Unit = { val allTags = fetchAllTags(image) println(allTags.minBy(_.full_size)) println(allTags.maxBy(_.full_size)) }