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.4k
【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
300
Rubyを好きになった過程
atgrandpa
3
1.5k
技術同人誌を執筆して得たこと
atgrandpa
3
1.5k
【Crystal】Concurrency
atgrandpa
3
860
初のサークル参加で気づいた小さなこと
atgrandpa
0
490
Other Decks in Technology
See All in Technology
_第3回__AIxIoTビジネス共創ラボ紹介資料_20250617.pdf
iotcomjpadmin
0
140
あなたの声を届けよう! 女性エンジニア登壇の意義とアウトプット実践ガイド #wttjp / Call for Your Voice
kondoyuko
1
170
プロダクトエンジニアリング組織への歩み、その現在地 / Our journey to becoming a product engineering organization
hiro_torii
0
110
PHPでWebブラウザのレンダリングエンジンを実装する
dip_tech
PRO
0
170
第9回情シス転職ミートアップ_テックタッチ株式会社
forester3003
0
150
Wasm元年
askua
0
100
菸酒生在 LINE Taiwan 的後端雙刀流
line_developers_tw
PRO
0
1.1k
成立するElixirの再束縛(再代入)可という選択
kubell_hr
0
950
(非公式) AWS Summit Japan と 海浜幕張 の歩き方 2025年版
coosuke
PRO
1
340
エンジニア向け技術スタック情報
kauche
0
110
A2Aのクライアントを自作する
rynsuke
1
150
Microsoft Build 2025 技術/製品動向 for Microsoft Startup Tech Community
torumakabe
1
210
Featured
See All Featured
Into the Great Unknown - MozCon
thekraken
39
1.9k
How to Think Like a Performance Engineer
csswizardry
24
1.7k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
48
5.4k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
Embracing the Ebb and Flow
colly
86
4.7k
Automating Front-end Workflow
addyosmani
1370
200k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
4
200
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.8k
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.8k
KATA
mclloyd
29
14k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
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