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
7k
From ㍻ to U+32FF
mitsuboshi
0
2k
Other Decks in Technology
See All in Technology
AWS SAW を広めたい @四国クラウドお遍路
kazzpapa3
0
200
OCI コスト管理
ocise
1
160
Autonomous Database Cloud 技術詳細 / adb-s_technical_detail_jp
oracle4engineer
PRO
15
40k
ことばをそろえる / Bridging the Terminology Gap
amaotone
5
1k
疎通2024
sadnessojisan
5
900
#Zenoh 完全に理解した 〜組込み純情篇〜
takasehideki
1
470
SORACOMで実現するIoTのマルチクラウド対応 - IoTでのクリーンアーキテクチャの実現 -
kenichirokimura
0
310
Oracle Exadata Database Service(Dedicated Infrastructure):サービス概要のご紹介
oracle4engineer
PRO
0
9.4k
20分で分かるIAM全機能 (拡大版) / 20240903-jawsug-yokohama-iam
opelab
3
140
Envoy External AuthZとgRPC Extensionを利用した「頑張らない」Microservices認証認可基盤
andoshin11
0
210
技術力あげたい
hisaichi5518
2
2.9k
タイミーのBraze活用 ~PUSH通知を活用したレコメンド~
ozeshun
2
150
Featured
See All Featured
Done Done
chrislema
180
16k
Why You Should Never Use an ORM
jnunemaker
PRO
53
8.9k
The Cost Of JavaScript in 2023
addyosmani
40
5.2k
Creatively Recalculating Your Daily Design Routine
revolveconf
215
12k
Principles of Awesome APIs and How to Build Them.
keavy
125
16k
How to Ace a Technical Interview
jacobian
275
23k
Building Your Own Lightsaber
phodgson
101
6k
Optimising Largest Contentful Paint
csswizardry
29
2.8k
Testing 201, or: Great Expectations
jmmastey
35
6.9k
Side Projects
sachag
451
42k
GraphQLの誤解/rethinking-graphql
sonatard
65
9.8k
Designing for humans not robots
tammielis
248
25k
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!!