Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 12661] ファイルの概要

このコミットは、Go言語の公式フォーマッタであるgofmtツールの使用例において、Windowsのコマンドプロンプト(cmd.exe)での表示互換性を向上させるための変更です。具体的には、gofmt-r(rewrite rule)フラグのヘルプメッセージに含まれていた非ASCII文字(Unicode文字)をASCII文字に置き換えることで、Windows環境での文字化けを防ぎ、より多くのユーザーが正しく情報を読み取れるようにすることを目的としています。

コミット

commit 7694da1f3bd5cd62cf656bbe0b4b7123e29bbc08
Author: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Date:   Thu Mar 15 16:38:27 2012 -0700

    cmd/gofmt: show ascii in usage.
    windows cmd.exe can't show utf-8 correctly basically.
    chcp 65001 may make it show, but most people don't have fonts which can
    show it.
    
    R=golang-dev, rsc, adg, gri, r
    CC=golang-dev
    https://golang.org/cl/5820060

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/7694da1f3bd5cd62cf656bbe0b4b7123e29bbc08

元コミット内容

cmd/gofmt: show ascii in usage.
windows cmd.exe can't show utf-8 correctly basically.
chcp 65001 may make it show, but most people don't have fonts which can
show it.

R=golang-dev, rsc, adg, gri, r
CC=golang-dev
https://golang.org/cl/5820060

変更の背景

この変更の背景には、Windowsのコマンドプロンプト(cmd.exe)がUTF-8エンコーディングの文字をデフォルトで正しく表示できないという問題があります。gofmt-rフラグのヘルプメッセージには、リライトルールの例としてα[β:len(α)] -> α[β:]という文字列が含まれていました。ここで使用されているギリシャ文字のα(アルファ)とβ(ベータ)は非ASCII文字であり、UTF-8でエンコードされています。

Windowsのcmd.exeは、デフォルトのコードページがUTF-8ではないため、これらの文字を正しく解釈・表示できず、文字化けが発生する可能性がありました。コミットメッセージにもあるように、chcp 65001コマンドを使用してコードページをUTF-8に変更することで表示できる場合もありますが、多くのユーザーは対応するフォントをインストールしていないため、この解決策は一般的ではありませんでした。

この問題を解決し、より多くのWindowsユーザーがgofmtのヘルプメッセージを正しく読めるようにするために、非ASCII文字をASCII文字に置き換えることが決定されました。これにより、gofmtの使いやすさとアクセシビリティが向上します。

前提知識の解説

  • gofmt: Go言語のソースコードを自動的にフォーマットするツールです。Go言語の標準的なコーディングスタイルに準拠させることで、コードの可読性を高め、チーム開発におけるスタイルの統一を促進します。go fmtコマンドとしてGoツールチェインに統合されています。
  • cmd.exe: Microsoft Windowsのコマンドラインインタープリタです。ユーザーがコマンドを入力してプログラムを実行したり、ファイルシステムを操作したりするためのテキストベースのインターフェースを提供します。
  • UTF-8: Unicode文字をエンコードするための可変長文字エンコーディング方式の一つです。世界中のほとんどの文字を表現できるため、Webページやソフトウェアで広く利用されています。
  • ASCII: American Standard Code for Information Interchangeの略で、コンピュータでテキストを表現するための最も基本的な文字コードの一つです。英数字、記号、制御文字など、128種類の文字を定義しています。UTF-8はASCIIと互換性があり、ASCII文字はUTF-8でも同じバイト列で表現されます。
  • コードページ (Code Page): コンピュータシステムが文字をエンコードおよびデコードするために使用する文字セットとエンコーディングの組み合わせを定義するものです。Windowsのcmd.exeは、地域設定に応じて異なるデフォルトのコードページを使用します。例えば、日本語環境ではShift-JIS(CP932)が使われることが多く、UTF-8(CP65001)とは異なります。
  • chcp 65001: Windowsのコマンドプロンプトで、現在のコードページをUTF-8(コードページ番号65001)に変更するコマンドです。これにより、コマンドプロンプトがUTF-8でエンコードされたテキストを正しく表示できるようになる場合があります。ただし、表示には対応するフォントが必要です。

技術的詳細

この変更は、gofmtのコマンドライン引数パーシングに使用されるflagパッケージのString関数に渡されるヘルプ文字列の修正に焦点を当てています。

Windowsのcmd.exeがUTF-8文字を正しく表示できない主な理由は、そのデフォルトのコードページ設定にあります。多くのWindowsシステムでは、cmd.exeはシステムのロケール設定に基づいて、UTF-8ではないコードページ(例: 日本語環境ではCP932)を使用します。このため、UTF-8でエンコードされた非ASCII文字がコマンドプロンプトに出力されると、文字コードの不一致により文字化けが発生します。

chcp 65001コマンドは、一時的にコマンドプロンプトのコードページをUTF-8に変更する解決策を提供しますが、これは以下の理由から万能ではありませんでした。

  1. ユーザーの手間: ユーザーが手動でコマンドを実行する必要があり、すべてのユーザーがこの知識を持っているわけではありません。
  2. フォントの制約: コードページをUTF-8に変更しても、コマンドプロンプトで使用されているフォントがUnicode文字(特にギリシャ文字のような特殊文字)をサポートしていなければ、やはり正しく表示されません。多くのデフォルトフォントは、限られた文字セットしか持っていません。

このコミットでは、これらの問題を根本的に解決するため、gofmt-rフラグのヘルプメッセージに含まれるαβという非ASCII文字を、それぞれASCII文字のabに置き換えるというシンプルなアプローチが取られました。これにより、ヘルプメッセージ全体がASCII文字のみで構成されるようになり、cmd.exeのデフォルト設定でも文字化けすることなく、確実に表示されるようになります。これは、機能に影響を与えることなく、ユーザーエクスペリエンスを向上させるための実用的な解決策です。

コアとなるコードの変更箇所

変更はsrc/cmd/gofmt/gofmt.goファイルの一箇所のみです。

--- a/src/cmd/gofmt/gofmt.go
+++ b/src/cmd/gofmt/gofmt.go
@@ -26,7 +26,7 @@ var (
 	// main operation modes
 	list        = flag.Bool("l", false, "list files whose formatting differs from gofmt's")
 	write       = flag.Bool("w", false, "write result to (source) file instead of stdout")
-	rewriteRule = flag.String("r", "", "rewrite rule (e.g., 'α[β:len(α)] -> α[β:]')")
+	rewriteRule = flag.String("r", "", "rewrite rule (e.g., 'a[b:len(a)] -> a[b:]')")
 	simplifyAST = flag.Bool("s", false, "simplify code")
 	doDiff      = flag.Bool("d", false, "display diffs instead of rewriting files")
 	allErrors   = flag.Bool("e", false, "print all (including spurious) errors")

コアとなるコードの解説

変更された行は、gofmtコマンドの-rフラグの定義です。

rewriteRule = flag.String("r", "", "rewrite rule (e.g., 'α[β:len(α)] -> α[β:]')")

この行は、flagパッケージを使用して、コマンドラインフラグ-rを定義しています。

  • 最初の引数"r"はフラグの名前です。
  • 二番目の引数""はフラグのデフォルト値です。
  • 三番目の引数"rewrite rule (e.g., 'α[β:len(α)] -> α[β:]')"は、このフラグのヘルプメッセージとして表示される文字列です。

このヘルプメッセージ内の例示文字列'α[β:len(α)] -> α[β:]'が、非ASCII文字であるαβを含んでいました。

変更後のコードは以下のようになります。

rewriteRule = flag.String("r", "", "rewrite rule (e.g., 'a[b:len(a)] -> a[b:]')")

ここでは、ヘルプメッセージの例示文字列が'a[b:len(a)] -> a[b:]'に変更されています。これにより、αaに、βbにそれぞれ置き換えられ、文字列全体がASCII文字のみで構成されるようになりました。

この変更により、Windowsのcmd.exegofmt -hgofmt --helpを実行した際に、-rフラグの説明が文字化けすることなく、正しく表示されるようになります。これは、機能的な変更ではなく、ユーザーインターフェースの表示に関する改善であり、特にWindowsユーザーの利便性を高めるためのものです。

関連リンク

参考にした情報源リンク