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.3k
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.3k
From ㍻ to U+32FF
mitsuboshi
0
2.1k
Other Decks in Technology
See All in Technology
第3回Snowflake女子会_LT登壇資料(合成データ)_Taro_CCCMK
tarotaro0129
0
200
レンジャーシステムズ | 会社紹介(採用ピッチ)
rssytems
0
170
Google Cloud で始める Cloud Run 〜AWSとの比較と実例デモで解説〜
risatube
PRO
0
110
マイクロサービスにおける容易なトランザクション管理に向けて
scalar
0
140
DevFest 2024 Incheon / Songdo - Compose UI 조합 심화
wisemuji
0
120
NW-JAWS #14 re:Invent 2024(予選落ち含)で 発表された推しアップデートについて
nagisa53
0
270
新機能VPCリソースエンドポイント機能検証から得られた考察
duelist2020jp
0
230
TSKaigi 2024 の登壇から広がったコミュニティ活動について
tsukuha
0
160
多領域インシデントマネジメントへの挑戦:ハードウェアとソフトウェアの融合が生む課題/Challenge to multidisciplinary incident management: Issues created by the fusion of hardware and software
bitkey
PRO
2
110
Qiita埋め込み用スライド
naoki_0531
0
5.1k
PHPからGoへのマイグレーション for DMMアフィリエイト
yabakokobayashi
1
170
小学3年生夏休みの自由研究「夏休みに Copilot で遊んでみた」
taichinakamura
0
170
Featured
See All Featured
4 Signs Your Business is Dying
shpigford
181
21k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
It's Worth the Effort
3n
183
28k
Speed Design
sergeychernyshev
25
670
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
32
2.7k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
Six Lessons from altMBA
skipperchong
27
3.5k
Side Projects
sachag
452
42k
RailsConf 2023
tenderlove
29
940
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
520
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
5
450
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!!