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.4k
From ㍻ to U+32FF
mitsuboshi
0
2.1k
Other Decks in Technology
See All in Technology
現場の種を事業の芽にする - エンジニア主導のイノベーションを事業戦略に装着する方法 -
kzkmaeda
2
2.1k
組織貢献をするフリーランスエンジニアという生き方
n_takehata
2
1.3k
エンジニアのためのドキュメント力基礎講座〜構造化思考から始めよう〜(2025/02/15jbug広島#15発表資料)
yasuoyasuo
18
6.9k
Amazon S3 Tablesと外部分析基盤連携について / Amazon S3 Tables and External Data Analytics Platform
nttcom
0
140
トラシューアニマルになろう ~開発者だからこそできる、安定したサービス作りの秘訣~
jacopen
2
2k
開発スピードは上がっている…品質はどうする? スピードと品質を両立させるためのプロダクト開発の進め方とは #DevSumi #DevSumiB / Agile And Quality
nihonbuson
2
3k
滅・サービスクラス🔥 / Destruction Service Class
sinsoku
6
1.6k
OpenID BizDay#17 KYC WG活動報告(法人) / 20250219-BizDay17-KYC-legalidentity
oidfj
0
250
ビジネスモデリング道場 目的と背景
masuda220
PRO
9
560
偶然 × 行動で人生の可能性を広げよう / Serendipity × Action: Discover Your Possibilities
ar_tama
1
1.1k
利用終了したドメイン名の最強終活〜観測環境を育てて、分析・供養している件〜 / The Ultimate End-of-Life Preparation for Discontinued Domain Names
nttcom
2
200
7日間でハッキングをはじめる本をはじめてみませんか?_ITエンジニア本大賞2025
nomizone
2
1.9k
Featured
See All Featured
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
10
1.3k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.1k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
40
2k
Bash Introduction
62gerente
611
210k
Building Your Own Lightsaber
phodgson
104
6.2k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
49k
Fireside Chat
paigeccino
34
3.2k
Become a Pro
speakerdeck
PRO
26
5.1k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.2k
Bootstrapping a Software Product
garrettdimon
PRO
306
110k
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!!