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
procedural-macros
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
cipepser
June 16, 2020
Technology
220
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
procedural-macros
cipepser
June 16, 2020
More Decks by cipepser
See All by cipepser
long-running-tasks
cipepser
3
680
layerx-fde-practices
cipepser
7
3.6k
NIKKEI Tech Talk#38
cipepser
0
1.3k
LayerXにおけるFDEについて
cipepser
4
4.1k
20250725-bet-ai-day
cipepser
4
730
Criterion-rs
cipepser
0
190
Practical Anonify
cipepser
2
930
Move for Libra written in Rust
cipepser
2
3.4k
How IBLT Works
cipepser
0
290
Other Decks in Technology
See All in Technology
スキルを作る、その前に!複数人で使われるスキルを 作るためのプロセス
junkifurukawa
2
370
ai_cording_with_k8s_knowledge.pdf
mochizuki875
1
320
"優秀な誰か"の下位互換にならないために
yut0naga1_fa
0
1k
AI時代のAPI開発を加速する品質ガードレール / API Quality Guardrails in the AI Era
yokawasa
0
170
おそらく日本で唯一のDevRelインターン生として
husengs7
0
170
AI 時代の Azure エンジニアリング ~ 私たちは何を磨き、何を任せるのか ~
chack411
1
550
AI駆動開発の時代になったのでトヨタ生産方式から見直す
terurou
6
5.5k
AI時代だからこそ推したい!Gitコマンド再入門
munakata
0
160
Codex概要
ymiya55
0
480
FOSS4Gを活用した自治体業務DXの試み
470715
0
140
オブザーバビリティを高める AI エージェント体験を考える / Designing AI Agent Experiences That Enhance Observability
aoto
PRO
2
320
二歩目のフロントエンド・ウェブアクセシビリティ
camiha
2
250
Featured
See All Featured
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
300
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
33
5.1k
Utilizing Notion as your number one productivity tool
mfonobong
4
610
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.5k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
300
What the history of the web can teach us about the future of AI
inesmontani
PRO
2
730
HDC tutorial
michielstock
2
950
WENDY [Excerpt]
tessaabrams
14
40k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
870
Building Applications with DynamoDB
mza
96
7.2k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
550
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
Transcript
Procedural macros入門 cipepser 2020/6/16 下町.rs #2
自己紹介 • cipepser(さいぺ) • リードエンジニア@LayerX ◦ R&Dチーム • 経歴 ◦
SIerで証券系システムのネットワーク設計、構築 ◦ Fintech会社で新規事業の立ち上げ • 趣味プロジェクト ◦ コンパイラ ◦ 正規表現ジェネレータ ◦ protocol buffersデコーダ ◦ (多くがやりかけ...)
Anonifyをリリースしました ソースコード ホワイトペーパー https://github.com/LayerXcom/anonify https://layerx.co.jp/wp-content/uploads/2020/06/anonify.pdf ドキュメント https://layerxcom.github.io/anonify-book/ スライド https://speakerdeck.com/layerx/anonify TEE内のテストにProcedural
macrosを利用している
アジェンダ 1. Procedural macros概要 2. 通常のRustマクロ 3. Procedural macrosでよく利用される3つマクロたち 4.
Custom Attributeの実装
Procedural macros概要
Procedural macrosをざっくりと理解する • Rust edition 2018から使えるようになった • 通常のRustマクロ ◦ macro_rules!
◦ パターンマッチ • Procedural macros ◦ Function-like macros ▪ custom!(...) ◦ Derive macros ▪ #[derive(CustomDerive)] ◦ Attribute macros ▪ #[CustomAttribute]
通常のRustマクロ
macro_rules! vec { () => ( $crate::vec::Vec::new() ); ($elem:expr; $n:expr)
=> ( $crate::vec::from_elem($elem, $n) ); ($($x:expr),+ $(,)?) => ( <[_]>::into_vec(box [$($x),+]) ); } Proceduralでない通常のRustマクロはパターンマッチがベース https://github.com/rust-lang/rust/blob/master/src/liballoc/macros.rs • (pattern) => (template); • *, +による繰り返し ◦ 参照は$で対になっている必要がある • exprやtyなどのフラグメント型 vec![]: vec![“a”; 3]: vec![1,2,3]:
Procedural macrosでよく利用される 3つマクロたち
proc_macro • Procedural macrosの実装をサポートするラ イブラリ • Cargo.tomlのlibで有効化して使う • proc_macro2というwrapperもある ◦
build.rsやmain.rsのような別のコンテキストに proc_macroの機能を持ち込みたいときに使う • TokenStreamを操作する ◦ ASTを直接操作するわけではない ◦ Vec<TokenTree>をcloneしやすくしたもの ◦ TokenTree = lexical token https://doc.rust-lang.org/proc_macro/
syn • 文字列を入力に構文解析 • validなRustコードであることを保証 • Structsでもろもろ定義されている ◦ 次ページでItemFnを例にみてみます https://docs.rs/syn/1.0.31/syn/
例)synで関数名を取得する pub struct ItemFn { pub attrs: Vec<Attribute>, pub vis:
Visibility, pub sig: Signature, pub block: Box<Block>, } pub struct Signature { pub constness: Option<Token![const]>, pub asyncness: Option<Token![async]>, pub unsafety: Option<Token![unsafe]>, pub abi: Option<Abi>, pub fn_token: Token![fn], pub ident: Ident, pub generics: Generics, pub paren_token: token::Paren, pub inputs: Punctuated<FnArg, Token![,]>, pub variadic: Option<Variadic>, pub output: ReturnType, } 関数名を持つ
quote • synのデータ構造を受け取り、トークン列に 変換し直す • #varで補完 ◦ 例)取得した関数名を利用したいとき https://docs.rs/quote/1.0.7/quote/ let
f = parse_macro_input!(input as ItemFn); let f_ident = &f.sig.ident; let q = quote!( #f_ident .. };
Custom Attributeの実装
Attributeの復習 #[test] fn check() { let x = 1; assert_eq!(x,
1); } #[test]を付与することで、check()に 「cargo test時に実行される」という意味を付与
やること:Custom Attributeで、cargo runでテストを走らせます use utils::{test_case, run_inventory_tests}; #[test_case] fn check() {
let x = 1; assert_eq!(x, 1); } #[test_case] fn fail() { let x = 1; assert_eq!(x, 2); } fn main() { run_inventory_tests!(); } • #[test_case] attributeを自作 • cargo runで実行 ◦ ✖ cargo test
ディレクトリ構造とCargo.toml [lib] proc-macro = true [dependencies] proc-macro2 = "1.0" quote
= "1.0" syn = "1.0" main関数を実装 標準出力の調整など Procedural macrosを実装 proc-macroを有効化
#[proc_macro_attribute] pub fn test_case(_attr: TokenStream, input: TokenStream) -> TokenStream {
let f = parse_macro_input!(input as ItemFn); let f_ident = &f.sig.ident; let q = quote!( #f inventory::submit!( utils::TestCase( concat!(module_path!(), "::", stringify!(#f_ident)).to_string(), #f_ident ) ); ); q.into() } Attributeを実装する TokenStreamをItemFnとしてparse 失敗したらコンパイルエラー attributeの名前を関数名にする 関数(check()やfail())が展開される
pub struct TestCase(pub String, pub fn() -> ()); inventory::collect!(TestCase); #[macro_export]
macro_rules! run_inventory_tests { () => { utils::test_start(); let mut ntestcases: u64 = 0u64; let mut failurecases: Vec<String> = Vec::new(); for t in inventory::iter::<utils::TestCase>.into_iter() { utils::test(&mut ntestcases, &mut failurecases, t.1, &t.0); } utils::test_end(ntestcases, failurecases) }; } #[test_case] attrを付与した関数を集める submit!した関数たちを集めてくる utils::test内でt.0を実行する
custom attributesを使ってみる use utils::{test_case, run_inventory_tests}; #[test_case] fn check() { let
x = 1; assert_eq!(x, 1); } #[test_case] fn fail() { let x = 1; assert_eq!(x, 2); } fn main() { run_inventory_tests!(); } attrを設定 attrを設定 main関数内でテストを実行
`cargo test`ではなく、`cargo run`でテストを実行する 関数名(checkやfail)も出力できた
• Procedural macrosと通常のマクロを紹介 • Procedural macrosでよく利用される3つマクロたち ◦ proc_macroで、Procedural macrosが有効になる ◦
synで、文字列からRustコードに構文解析する ◦ quoteで、synのデータ構造からRustコードに変換し直す • Custom Attributeを実装した ◦ 自分でも動かしたい!という方は以下にソースコードを公開してます。 ◦ https://github.com/cipepser/rust-custom-attribute まとめ
References • proc_macro - Rust https://doc.rust-lang.org/proc_macro/ • O'Reilly Japan -
プログラミングRust https://www.oreilly.co.jp/books/9784873118550/ • Procedural Macros - The Rust Reference https://doc.rust-lang.org/reference/procedural-macros.html • D - マクロ - The Rust Programming Language https://doc.rust-jp.rs/book/second-edition/appendix-04-macros.html • proc_macro2 - Rust https://docs.rs/proc-macro2/1.0.18/proc_macro2/ • syn - Rust https://docs.rs/syn/1.0.31/syn/ • quote - Rust https://docs.rs/quote/1.0.7/quote/ • inventory - Rust https://docs.rs/inventory/0.1.6/inventory/ • Procedural Macros に入門していたずらしてみた - Don't Repeat Yourself https://yuk1tyd.hatenablog.com/entry/2018/12/25/192041 • Procedural macros 雑入門 - slideship.com https://slideship.com/users/@statiolake/presentations/2019/07/CZ9wX4Zi8R93MhxN7jRBK5/?p=2
ブロックチェーン技術をもとに、「新たな経済基盤」をつくりだす。 それは、信用や評価のあり方を変え、 業務や生産をはじめとした経済活動の摩擦を解消し、 この国の課題である生産性向上を実現する。 私たちは、そう信じて行動し続けます。 ブロックチェーンが実装された社会、 そこには、これまでの延⻑にはないまったく新しい可能性が広がっている。 LayerXは、デジタル社会への発展を後押しすることで、 経済史に新たな1ページを刻んでいきます。