Skip to content

Instantly share code, notes, and snippets.

@kojix2
Last active September 18, 2025 03:52
Show Gist options
  • Select an option

  • Save kojix2/e1361d6f828ea452c90f049673d033f7 to your computer and use it in GitHub Desktop.

Select an option

Save kojix2/e1361d6f828ea452c90f049673d033f7 to your computer and use it in GitHub Desktop.
ChatGPTによるCrystalのOptionParser改善計画

OptionParser 改善メモ(日本語 / English)

目的: 既存の互換性を保ちつつ、使い勝手・表現力・国際化・エラーメッセージ品質を向上するロードマップ


1) 短オプション束ね対応(Short option bundling, -abc

  • 用語: 短オプション束ね / short option bundling

  • 要点:

    • -abc-a -b -c と等価に解釈(後方互換: -n10-n 10 を維持)。
    • 束ね中に 必須値(required) のフラグが来たら、残りは値として扱う(例: -n10)。
    • 任意値(optional) の場合、GNUモードと非GNUモードで既存の“食べ方”規約を踏襲。
  • API/挙動(EN):

    • Respect legacy -lX (“first flag, rest as value”) while enabling -abc expansion.

2) 型付きオプション(Typed options)

  • 用語: 型付きパース / typed parsing

  • 要点:

    • on("-n N", Int32, "...") { |n| ... } のように 型を宣言して値を自動変換。
    • 失敗時のメッセージを統一(例: Invalid value for --num: expected Int32)。
    • Array(T)多回数指定の自動収集(repeatable options → Array)。
  • API(EN):

    opts.on("--num N", Int32, "count") { |n| num = n }
    opts.on("--include PATH", Array(String), "collect") { |paths| includes = paths }

3) 否定フラグ(Negated boolean flags, --[no-]flag / --no-flag

  • 用語: 否定フラグ / negated flags

  • 要点:

    • --[no-]color--color / --no-color の両方を受理、Bool を渡す。
    • あるいは on("--color", Bool, ...)--no-color を自動許容。
  • API(EN):

    opts.on("--[no-]color", "toggle color") { |b| color = b }
    # or
    opts.on("--color", Bool, "toggle color") { |b| color = b }

4) サブコマンドの強化(Subcommand DSL / nested parser)

  • 用語: サブコマンド専用パーサ / per-subcommand parser

  • 要点:

    • サブコマンドのブロックへ 子 OptionParser を渡し、個別のフラグ群・ヘルプを定義。
    • 既存の「非ダッシュ全消去」方式は維持しつつ、arity で新旧APIを両立
  • API(EN):

    opts.on("commit", "record changes") do |sub|
      sub.banner = "Usage: git commit [options]"
      sub.on("-m MSG", "--message=MSG", "message") { |m| msg = m }
    end

5) CJK 幅対応の整形(East Asian width-aware formatting)

  • 用語: 表示幅 / display width(全角=2, 半角=1)

  • 要点:

    • ヘルプ整形のパディングに East Asian Width を反映して桁ズレ解消。
    • 改行時のインデントも表示幅に応じて計算。
  • Notes(EN): Replace String#size with display_width in help layout.


6) 候補提示(Did-you-mean suggestions)

  • 用語: 近似候補提示 / did-you-mean

  • 要点:

    • 未知フラグでレーベンシュタイン距離等により 候補を提案
    • 例: Invalid option: --hep. Did you mean --help?
  • Config(EN): Make suggestion threshold tunable (e.g., distance ≤ 2).


7) 既定値・必須・環境変数(Defaults / required / env fallback)

  • 用語: 既定値 / defaults、必須 / required、環境変数からの補完 / env fallback

  • 要点:

    • on(..., default: "x", required: true, env: "FOO") を宣言的に。
    • 未指定時は ENV["FOO"] → default → Missing の順に評価。
  • API(EN):

    opts.on("--token TOKEN", String, "api token", env: "API_TOKEN", required: true) { |t| token = t }

8) 繰り返し指定(Repeatable options)

  • 用語: 多回数指定 / repeatable options

  • 要点:

    • 同一フラグの複数回指定を 自動的に配列へ集約
    • Array(T) 指定がない場合でも repeat: true などの明示も可能に。
  • API(EN):

    opts.on("--include PATH", String, repeat: true) { |p| includes << p }

9) エラーポリシーの統一(Error policy & exit codes)

  • 用語: エラーハンドラ / error handler、終了コード / exit code

  • 要点:

    • デフォルトは従来通り例外だが、CLI向けテンプレを提供: stderr に概要 + --help 提示 → exit(1)
  • API(EN):

    parser.error_policy = :cli # standardized stderr + exit(1)

10) gnu_optional_args の明確化とドキュメント(Documentation for GNU vs non-GNU semantics)

  • 用語: GNU 任意引数規約 / GNU optional-arg semantics

  • 要点:

    • spec で確立された「スペース後は取らない(GNU)」と「未登録なら取る(非GNU)」を例付きで明文化。
    • 束ね導入後の相互作用も明示(例: -o value の処理)。

11) 高速化の余地(Performance micro-optimizations)

  • 用語: 状態保存のコスト / state preservation overhead

  • 要点:

    • with_preserved_stateclone軽量化(必要な場合のみ、あるいは構造共有)。
    • ハンドラ検索のルックアップ回数を削減(短束ね時の内部ループ最適化)。

12) API エルゴノミクス(Ergonomics)

  • 用語: 糖衣構文 / sugar、宣言的一貫性 / declarative consistency

  • 要点:

    • on の引数順・オーバーロードを整理(flag(s), type?, desc, opts?)。
    • エイリアス定義を簡便に(alias: ["-v"] 等)。

13) 未知/欠落ハンドラの拡充(Unknown & missing handlers)

  • 用語: 未知引数 / unknown args、必須値欠落 / missing option

  • 要点:

    • unknown_args理由(「未登録」「-- 以降」など)をタグ付けして渡す。
    • missing_option期待型・例を自動付記(型付き導入後)。

14) テストと互換性(Specs & compatibility)

  • 用語: 後方互換 / backward compatibility、回帰テスト / regression tests

  • 要点:

    • 既存 spec を厳守しつつ、新機能の 追加 spec を先に投入(pending も可)。
    • 束ね導入時は -ll(legacy “rest as value”)の保持をテストで明記

15) 国際化(Internationalization of help output)

  • 用語: ロケール / locale、メッセージ多言語化 / i18n of messages

  • 要点:

    • エラー・ヘルプの 文言を差し替え可能に(メッセージカタログ / proc 差替え)。
    • CJK 幅対応と合わせて 日本語ヘルプでも整う。

参考のスニペット(Snippets)

型付き + 繰り返し + 環境変数(Typed + repeatable + env)

opts.on("--threads N", Int32, "threads", env: "APP_THREADS", default: 4) { |n| threads = n }
opts.on("--include PATH", String, "include paths", repeat: true) { |p| includes << p }

否定フラグ(Negated flag)

opts.on("--[no-]color", "enable/disable color") { |b| color = b }

サブコマンド(Subcommand parser)

opts.on("serve", "start server") do |sub|
  sub.on("--port N", Int32, "port") { |p| port = p }
  sub.on("--[no-]tls", "TLS") { |b| tls = b }
end

移行上の注意(Migration notes)

  • 短束ね導入は既存 -lX 互換の保持が最重要。最初の required/optional 到達で打ち切りという規則で整合。
  • optional の“食べ方”は 現行 spec に完全準拠(GNU/非GNU で分岐)。
  • 新 API は 後方互換の糖衣に留め、旧 API を deprecate しない。

必要なら、この方針に沿った 追加 spec(日本語コメント付き)最小差分パッチをまとめて出せます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment