Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
【Crystal】Macroについて
Search
at_grandpa
June 21, 2018
Technology
3
1.5k
【Crystal】Macroについて
東京 Crystal 勉強会 #6 in 渋谷
https://crystal.connpass.com/event/90745/
イベント資料です。
at_grandpa
June 21, 2018
Tweet
Share
More Decks by at_grandpa
See All by at_grandpa
技術書典5でチャレンジしたあれこれ
atgrandpa
3
1.9k
CSS組版おもしろい!
atgrandpa
1
310
Rubyを好きになった過程
atgrandpa
3
1.5k
技術同人誌を執筆して得たこと
atgrandpa
3
1.5k
【Crystal】Concurrency
atgrandpa
3
880
初のサークル参加で気づいた小さなこと
atgrandpa
0
490
Other Decks in Technology
See All in Technology
Webアプリケーションにオブザーバビリティを実装するRust入門ガイド
nwiizo
7
800
ChatGPTとPlantUML/Mermaidによるソフトウェア設計
gowhich501
1
130
AIエージェント開発用SDKとローカルLLMをLINE Botと組み合わせてみた / LINEを使ったLT大会 #14
you
PRO
0
110
Autonomous Database - Dedicated 技術詳細 / adb-d_technical_detail_jp
oracle4engineer
PRO
4
10k
現場で効くClaude Code ─ 最新動向と企業導入
takaakikakei
1
240
Aurora DSQLはサーバーレスアーキテクチャの常識を変えるのか
iwatatomoya
1
920
MCPで変わる Amebaデザインシステム「Spindle」の開発
spindle
PRO
3
3.2k
人工衛星のファームウェアをRustで書く理由
koba789
15
7.7k
20250903_1つのAWSアカウントに複数システムがある環境におけるアクセス制御をABACで実現.pdf
yhana
3
550
サラリーマンの小遣いで作るtoCサービス - Cloudflare Workersでスケールする開発戦略
shinaps
2
440
DevIO2025_継続的なサービス開発のための技術的意思決定のポイント / how-to-tech-decision-makaing-devio2025
nologyance
1
390
ガチな登山用デバイスからこんにちは
halka
1
240
Featured
See All Featured
KATA
mclloyd
32
14k
Done Done
chrislema
185
16k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
920
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
358
30k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
9
810
Statistics for Hackers
jakevdp
799
220k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
188
55k
The Language of Interfaces
destraynor
161
25k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
13k
Unsuck your backbone
ammeep
671
58k
Transcript
Macroについて 2018.06.21 @at_grandpa Crystal 勉強会 #6 in 渋谷
@at_grandpa
圧倒亭グランパのブログ
Crystal Advent Calendar 2017
Crystal Advent Calendar 2017
Macroについて
✔ Macro の雰囲気を話します ✔ 細かい syntax などはドキュメント参照
None
✔ 「Crystalのコード」を書くコード ✔ コンパイル前に実行される Macro
None
Macro定義
Macro呼出
Macro呼出 Macro展開
Macro展開後のコードがコンパイルされる
どういった利点があるのか
✔ 重複を排除しやすい ✔ メタプロ風味 ✔ DSLを提供しやすい
重複を排除しやすい
None
重複
重複
重複 重複排除
getter だけなのに複雑では…
getterあります Object クラスに定義されている Macro
便利 Macro たくさん! https://crystal-lang.org/api/Object.html
Crystal Advent Calendar 2017 便利 Macro 紹介してます
重複を排除しやすい ✔ ある程度は重複排除できる ✔ 便利 Macro がすでにいくつかある
メタプロ風味
✔ rubyだと instance_methods と define_method ? 各メソッドの実行時間を出力したい! お題
簡単なライブラリクラスを書いてみる 「MethodProf」クラスとでも名付けよう
まずは使用例
出来上がりイメージ
出来上がりイメージ 1秒 sleep して String を返す
出来上がりイメージ 100万回 String を結合する
出来上がりイメージ 100万回 String を2つ結合している
出来上がりイメージ MethodProf を include して Macro を展開している
出来上がりイメージ インスタンスを生成してメソッド呼び出し
出来上がりイメージ
MethodProf クラス
None
macro構文で定義(引数はio)
・@type は型情報にアクセスできる ・@type.methods で型に定義されているmethodの配列を得る - ArrayLiteral(Crystal::Macros::Def) ・initializeメソッドは計測対象から外すので配列から除去 → initialize 以外の
method 情報で for を回す
・展開される Crystal のコードを定義 ・呼出先に def 構文が展開される
・メソッド名は Crystal::Macros::Def#name で得る ・引数は Crystal::Macros::Def#args で得る - 「*」をつけて splat展開 している
・計測のために時間を保持
・lambda を生成 - 引数は対象のメソッドと同じ - メソッドの中身は Crystal::Macros::Def#body で得る ・lambda を即座に
call する - 渡す引数は args の名前を羅列 - *(m.args) は型情報も含まれてしまうので、ここでは名前だけ展開 ・return_value に格納
・計測結果を io に出力
・lambda の結果を返す
Macro を展開するとこうなります loop2を例に
Macro定義 loop2展開後
Macro定義 loop2展開後
Macro定義 loop2展開後
Macro定義 loop2展開後
Macro定義 loop2展開後
Macro定義 loop2展開後
✔ ASTNodeの情報からコンパイル時にコードを生成 ✔ splat展開が優秀だった! ✔ もちろん「動的なclass定義」はできない メタプロ風味
DSLを提供しやすい
https://github.com/at-grandpa/clim
https://github.com/at-grandpa/clim ✔ ruby の thor 風 syntax ✔ オプションの型指定 ✔
default / required ✔ サブコマンド ✔ カスタムヘルプ
None
None
None
すべて Macro ・最終的に全てクラスやメソッドの定義に展開される
None
コンパイル時に raise で落としてエラーメッセージを出す
DSLに渡された文字列を使ってオプションの独自のクラスを定義 DSLに渡された文字列を使ってコマンドの独自のクラスを定義
DSLを提供しやすい ✔ 複雑なコードも簡単に記述できるようになる
✔ 重複を排除しやすい ✔ メタプロ風味 ✔ DSLを提供しやすい Macro の利点おさらい
Macro周りのtips
デバッグしづらいのでは?
エラー文が親切です!
エラー文が親切です! Macro 展開後のどこでエラーが起きているかわかる
エラー文が親切です! エラー内容も具体的
`crystal tool expand` があります! ✔ ファイルとカーソル位置指定 ✔ カーソル位置の Macro を展開して表示
crystal tool expand ファイルとカーソル位置を指定
crystal tool expand 展開されたコードを見ることができる
`macro` ディレクティブなしでもOK
実は直接書けます 環境変数でcrystalコードを切り替えたりできます
展開後は正しいのにエラーなんだけど
❌ Macro展開後、全体のコードが正しい ⭕ Macro展開のみで出来たコードが正しい
❌ Macro展開後、全体のコードが正しい ⭕ Macro展開のみで出来たコードが正しい
❌ Macro展開後、全体のコードが正しい ⭕ Macro展開のみで出来たコードが正しい この Macro 展開だけでは `when` だけしか展開されない →
Macro展開だけのコードを見ると syntax error → コンパイラ落ちる
begin ~ end を使う
begin ~ end を使う begin ~ end で囲めば、 ひとつのMacroとして扱われる →
展開後のコードは正しい ※ 実は {% begin %} は {% if true %} のシンタックスシュガーです
まとめ
✔ 「Crystalのコード」を書くコード ✔ コンパイル前に実行される ✔ 重複を排除しやすい ✔ メタプロ風味 ✔ DSLを提供しやすい
Macro とは
Happy Crystalling fin