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
Good to know yaml
Search
MITSUBOSHI
December 14, 2019
Technology
0
1.4k
Good to know yaml
MITSUBOSHI
December 14, 2019
Tweet
Share
More Decks by MITSUBOSHI
See All by MITSUBOSHI
Google Play IAB(In-App Billing) 〜Railsでのサーバサイド対応のすべて〜
mitsuboshi
4
7.7k
From ㍻ to U+32FF
mitsuboshi
0
2.3k
Other Decks in Technology
See All in Technology
JTCにおける内製×スクラム開発への挑戦〜内製化率95%達成の舞台裏/JTC's challenge of in-house development with Scrum
aeonpeople
0
230
企業の生成AIガバナンスにおけるエージェントとセキュリティ
lycorptech_jp
PRO
2
180
Webアプリケーションにオブザーバビリティを実装するRust入門ガイド
nwiizo
7
840
バイブスに「型」を!Kent Beckに学ぶ、AI時代のテスト駆動開発
amixedcolor
2
570
AWSを利用する上で知っておきたい名前解決のはなし(10分版)
nagisa53
10
3.1k
CDK CLIで使ってたあの機能、CDK Toolkit Libraryではどうやるの?
smt7174
4
190
DevIO2025_継続的なサービス開発のための技術的意思決定のポイント / how-to-tech-decision-makaing-devio2025
nologyance
1
400
会社紹介資料 / Sansan Company Profile
sansan33
PRO
6
380k
slog.Handlerのよくある実装ミス
sakiengineer
4
190
AWSで始める実践Dagster入門
kitagawaz
1
620
要件定義・デザインフェーズでもAIを活用して、コミュニケーションの密度を高める
kazukihayase
0
120
新アイテムをどう使っていくか?みんなであーだこーだ言ってみよう / 20250911-rpi-jam-tokyo
akkiesoft
0
280
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.6k
The Pragmatic Product Professional
lauravandoore
36
6.9k
Embracing the Ebb and Flow
colly
87
4.8k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.9k
It's Worth the Effort
3n
187
28k
Building Applications with DynamoDB
mza
96
6.6k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
36
2.5k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
580
For a Future-Friendly Web
brad_frost
180
9.9k
BBQ
matthewcrist
89
9.8k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3k
Transcript
Good to know yaml
self.introduction.to_yaml
今日話すこと/話さないこと 今日話すこと - YAMLのAST周り (※ざっくり) - 実世界でYAMLのASTを理解して解決できる問題とは 今日話さないこと - syckについて
- Psych::Nodes以外はあまり触れない - yamlの詳細な仕様について - JSONとの規格の違い
基本編
YAMLとPsych
yamlとは https://en.wikipedia.org/wiki/YAML
yamlとは (簡潔に & ほぼ「るびま」からコピペ) - 構造化されたデータを表現するためのフォーマット - YAMLでは主に次の 3 つの組み合わせでデータを表現する
- Sequence: Rubyで言うと `Array` - Mapping: Rubyで言うと `Hash` - Scalar: (文字列、数値、真偽値など ) https://magazine.rubyist.net/articles/0009/0009-YAML.html
gem ‘psych’とは - yamlのバックエンドライブラリ(Ruby 1.9.3から標準化) - YAML バージョン 1.1に対応 -
過去のyamlバックエンドライブラリは `Syck ` - YAML バージョン 1.0に対応していた - libyamlのRubyで扱えるwrapper - `YAML.load`, `.load_file`, `.parse`, `.parse_file`とかをよく使うと思うんですけど、 Rubyオブジェクトへの変換処理はgem ‘psych’ が担っています https://github.com/ruby/psych
Psych::Nodes
Psych::Nodes::Stream - AST のルートノード - ノードの子ノードは1個以上 && Psych::Nodes::Documentオブジェクトである - `#children`
で Array<Psych::Nodes::Document> にアクセス出来る https://docs.ruby-lang.org/ja/latest/class/Psych=3a=3aNodes=3a=3aStream.html
Psych::Nodes::Document - Psych::Nodes::Stream の子ノード - 1個の子ノードを持つ - 子ノードは以下のいずれかのインスタンス - Psych::Nodes::Sequence
- Psych::Nodes::Mapping - Psych::Nodes::Scalar - 唯一の子ノードには `#root` でアクセス出来る https://docs.ruby-lang.org/ja/latest/class/Psych=3a=3aNodes=3a=3aDocument.html
Psych::Nodes::Mapping - Rubyで言うところの `Hash` - 0 個以上の子ノードを持つ - 子ノードの個数は偶数である -
子ノードは以下のいずれかのインスタンス - Psych::Nodes::Sequence - Psych::Nodes::Mapping - Psych::Nodes::Scalar - Psych::Nodes::Alias https://docs.ruby-lang.org/ja/latest/class/Psych=3a=3aNodes=3a=3aMapping.html
Psych::Nodes::Scalar - ASTの葉ノード #<- これだけでも覚えて帰ってくだ さい - よって、子ノード(children)を持ちません - `#value`
でscalarの値にアクセスできる https://docs.ruby-lang.org/ja/latest/class/Psych=3a=3aNodes=3a=3aScalar.html
Psych::Nodes::Sequence - Rubyで言うところの `Array` - 0 個以上の子ノードを持つ - 子ノードは以下のいずれかのインスタンス -
Psych::Nodes::Sequence - Psych::Nodes::Mapping - Psych::Nodes::Scalar - Psych::Nodes::Alias https://docs.ruby-lang.org/ja/latest/class/Psych=3a=3aNodes=3a=3aSequence.html
Psych::Nodes::Alias - ASTの葉ノード - よって、子ノード(children)を持ちません - `#anchor` で別の YAML の要素を指す
https://docs.ruby-lang.org/ja/latest/class/Psych=3a=3aNodes=3a=3aAlias.html
ちょっと詳しく
こんなyamlがあったとさ
None
None
None
実践編
[問題] 重複したkeyを持つyamlファイルの検出 - grepだと階層構造意識できず辛い - `YAML.load_file(‘/sample.yml’)` 時には既に消失 - Hash#mergeと同じで同名keyがある場合は上書かれます -
Rubyで検出する方法 is ... ※リッチなIDEとかだとwarning出してくれることを昨日知ったのは話さない
[問題] 重複したkeyを持つyamlファイルの検出 - gem 'doorkeeper' に活きがいいyml があったのでそれを使います - ↑ファイルに重複したkeyを仕込みま した
- 計: 147行のymlファイル https://gist.github.com/MITSUBOSHI/5085468e763c5cd74854df854f8e4ae8
案1 オープンクラス https://gist.github.com/MITSUBOSHI/82840c8bad7a07f722ae241bd7f8e892
案1 オープンクラス 解決 https://gist.github.com/MITSUBOSHI/82840c8bad7a07f722ae241bd7f8e892
案2 Psych::TreeBuilderの継承 https://gist.github.com/MITSUBOSHI/77e4903e6a6274a30b997488234d535c
案2 Psych::TreeBuilderの継承 解決 https://gist.github.com/MITSUBOSHI/77e4903e6a6274a30b997488234d535c
案3 ASTから頑張る - `Psych::Handler#end_mapping` (`Psych::TreeBuilder` の継承元クラス)を使った ほうが断然スマートではある - けど、YAMLのAST nodeの理解のためにちょっと頑張ってみる
過去(平成時代)の自分への挑戦 - 某何かで重複したmapping keyを持つyamlファイルがあった - すごくイラッとした - YAMLのASTから検出出来るんじゃない?と思って頑張った - 当時
`Psych::Handler#end_mapping` を知らなかった... - 今見ると何をしているのかわからない実装... https://gist.github.com/MITSUBOSHI/ef3e8724715ed094f7737372186e59ed
※コードの断片
読めない
gem ‘yamcha’ なので、今回の登壇を期に作り直して、gemにしました 名前の由来は - Yaml Checker -> やむちぇ ->
やむちゃ -> Yamcha(飲茶) ※栽培マンに負けるほど貧弱なgemです https://github.com/MITSUBOSHI/yamcha
Yamchaの構成 Yamcha::Validator -> メインで呼び出される Yamcha::Composer -> ASTからhashを組み立てるもの Yamcha::NodeResolver -> AST
nodeを上手い感じで隠蔽する なにか (※上手い感じ = 雰囲気)
Yamcha::NodeResolver
Yamcha::NodeResolver#resolver
Yamcha::NodeResolver::Base ※Abstract Class
Yamcha::NodeResolver::Mapping
Yamcha::NodeResolver::Scalar
Yamcha::Composer
Yamcha::Composer#recursively_compose
Yamcha::Composer
Yamcha::Composer#scalar_and_sequence?
Yamcha::Composer#scalar_and_mapping?
Yamcha::Composer#scalar_and_saclar?
Yamcha::Validator
Yamcha::Validator::DuplicatedMappingKey
Yamcha::Composer#compose_hash
案3 ASTから頑張る 解決 https://github.com/MITSUBOSHI/yamcha
時間の関係上出来ていないこと(言い訳) - Psych::Nodes::Aliasに未対応 - database.yml等はalias記法用いることが多いと思っているが、mapping keyの 重複しがちなケースは肥大化しがちなi18n系のymlであって... - Psych::Nodes::Scalarを値は文字列のまま -
Psych::Nodes::Sequenceの対応雑
Psych::Nodes::Sequenceの対応雑 - SequenceのchildrenがMappingであるケースが考慮できていない
参考資料 - https://github.com/ruby/psych - https://magazine.rubyist.net/articles/0009/0009-YAML.html 関連の記事(※syckについて) - https://ruby-doc.org/stdlib-2.6.5/libdoc/psych/rdoc/Psych.html - https://docs.ruby-lang.org/ja/latest/library/psych.html
- https://www.arp242.net/yaml-config.html
Thank you!!
時間が余ったら
Psych::ScalarScanner - YAMLのScalar型を読み込み、Rubyのbuilt-in型に変換するクラス - gem ‘yamcha’ ではScalar型を文字列のまま放置している実装だった - Psych::Nodes::Nodeを継承するクラスインスンタンスの`#to_ruby` 実行時に呼ば
れる - 「このScalar型は最終的にRubyでは何のクラスとして扱われるのか?」を知るのに 便利 & 楽しい https://docs.ruby-lang.org/ja/latest/class/Psych=3a=3aScalarScanner.html
None
https://github.com/ruby/psych/blob/master/lib/psych/scalar_scanner.rb ※コードの断片
Thank you again!!