YAML型変換:予期しないブール値と数値のパース

YAMLが値をブール値、数値、nullに自動変換する仕組みを理解します。悪名高い「ノルウェー問題」とクォート戦略による意図しない型変換の防止方法を学びます。

Validation

詳細な説明

YAML型変換

YAMLの最も議論の多い機能の一つが、積極的な自動型検出です。クォートされていない値はルールセットに従ってパースされ、驚くべき結果を生み出し、追跡が困難なバグにつながる可能性があります。

ノルウェー問題

最も有名なYAML型変換の問題:

countries:
  - GB    # 文字列 "GB"
  - FR    # 文字列 "FR"
  - NO    # ブールfalseとしてパースされる!
  - DE    # 文字列 "DE"

YAML 1.1では、YAMLが多くのブールリテラルを認識するため、NO はブール false として解釈されます:yes/notrue/falseon/offy/n(大文字小文字区別なし)。

YAML 1.1のブール値

以下のすべてがブールとしてパースされます:

True値 False値
trueTrueTRUE falseFalseFALSE
yesYesYES noNoNO
onOnON offOffOFF
yY nN

YAML 1.2ではブールは truefalse のみに制限されていますが、多くのパーサーは依然としてYAML 1.1のルールを使用しています。

数値変換

version: 1.0      # Float 1.0、文字列"1.0"ではない
build: 0123       # 8進数83、文字列"0123"ではない
phone: 1-800-555  # 文字列(有効な数値パターンではない)
port: 8080        # 整数8080
price: 9.99       # Float 9.99
infinity: .inf    # 無限大
not_a_number: .nan  # NaN

Null値

value: null      # Null
value: ~         # Null
value:           # Null(空の値)
value: Null      # Null
value: NULL      # Null

修正方法:文字列をクォートする

最も安全なアプローチは、文字列のままにすべき値をクォートすることです:

countries:
  - "GB"
  - "FR"
  - "NO"     # 正しく文字列になる
  - "DE"

version: "1.0"   # 文字列、floatではない
enabled: "yes"   # 文字列、ブールではない

フォーマッターとリンターのルール

モダンなYAMLツールが役立ちます:

  • yamllint にはクォートされていないブールのような値について警告する truthy ルールがある
  • 一部のフォーマッターはあいまいな値を自動クォートするオプションを提供
  • JSON Schema検証で特定フィールドの文字列型を強制できる

ユースケース

型変換バグはYAML関連の本番インシデントで最も一般的なものの一つです。'on: push'が'true: push'としてパースされるCIパイプライン、NOがfalseになる国コードリスト、小数精度を失うバージョン番号1.0 — これらはすべて実際の問題です。型変換の理解はYAML設定ファイルを書くすべての人にとって不可欠です。

試してみる — YAML Formatter & Validator

フルツールを開く