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

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

このコミットは、Go言語の公式ドキュメントの一部である doc/articles/image_draw.html 内のコード例の表示に関するバグを修正するものです。具体的には、image_draw.html の「円の描画」に関するセクションで、同じコードスニペットが二度表示されてしまう問題を解決しています。この修正により、本来意図されていた「型定義」と「その型を使用したコードスニペット」が正しく表示されるようになりました。

コミット

commit fc9f65a6a09377b49e7b21bb8dcad3a2260edfb8
Author: Rob Pike <r@golang.org>
Date:   Fri Mar 23 17:02:21 2012 +1100

    doc/articles/image_draw.html: fix circle example
    It was showing the same snippet twice instead of the type definition and snippet.
    
    R=golang-dev, iant
    CC=golang-dev
    https://golang.org/cl/5875045

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

https://github.com/golang/go/commit/fc9f65a6a09377b49e7b21bb8dcad3a2260edfb8

元コミット内容

doc/articles/image_draw.html: fix circle example
It was showing the same snippet twice instead of the type definition and snippet.

R=golang-dev, iant
CC=golang-dev
https://golang.org/cl/5875045

変更の背景

このコミットの背景には、Go言語の公式ドキュメントにおけるコードスニペットの表示に関する不具合がありました。doc/articles/image_draw.html という記事では、image パッケージと draw パッケージを使った画像の描画方法について解説しており、その中に円の描画に関するコード例が含まれていました。しかし、このコード例が意図せず同じスニペットを2回表示してしまうという問題が発生していました。

Go言語のドキュメントシステムでは、Goのソースコードファイル内に特別なコメント(OMIT マーカー)を記述することで、ドキュメントに埋め込むコードスニペットの開始と終了を制御しています。image_draw.html は、{{code}} というディレクティブを使用して、doc/progs/image_draw.go から特定のコードブロックを読み込んでいました。

問題は、image_draw.html が参照していた image_draw.go 内のコードブロックの指定方法にありました。同じマーカー名(CIRCLE)が、型定義と実際の使用例の両方を指すように設定されていたため、結果として同じ内容が重複して表示されてしまっていたのです。このコミットは、この重複表示を解消し、読者が期待する「型定義」と「その型を使った具体的な描画ロジック」がそれぞれ独立したスニペットとして正しく表示されるようにすることを目的としています。

前提知識の解説

このコミットを理解するためには、以下のGo言語のドキュメントシステムと関連する概念についての知識が必要です。

  1. Go言語のドキュメントシステムと godoc: Go言語には、ソースコードから自動的にドキュメントを生成する godoc というツールがあります。godoc は、Goのソースコード内のコメントや特定の構造(関数、型、変数など)を解析し、HTML形式のドキュメントを生成します。これにより、コードとドキュメントの一貫性が保たれやすくなります。

  2. OMIT マーカー: godoc や Goのドキュメント生成システムでは、ソースコード内の特定の行をドキュメントに含めるか除外するかを制御するために、OMIT マーカーを使用します。これは、// START OMIT// END OMIT// OMIT といった形式のコメントとして記述されます。

    • // START OMIT// END OMIT: これらのマーカーで囲まれたコードブロックがドキュメントに含められます。
    • // OMIT: このマーカーが記述された行はドキュメントから除外されます。 このコミットで重要なのは、//CIRCLE OMIT//STOP OMIT のように、特定のキーワードと OMIT を組み合わせることで、ドキュメント側からそのキーワードに対応するコードブロックを抽出できる点です。
  3. {{code}} ディレクティブ: Goのドキュメント記事(特に doc/articles ディレクトリ内のHTMLファイル)では、Goのソースコードファイルからコードスニペットを埋め込むために {{code}} という特別なディレクティブを使用します。このディレクティブは、以下のような形式で記述されます。

    {{code "path/to/file.go" `/START_MARKER/` `/END_MARKER/`}}
    
    • "path/to/file.go": コードスニペットを抽出するGoソースファイルのパス。
    • /START_MARKER/: スニペットの開始を示す正規表現または OMIT マーカーのキーワード。
    • /END_MARKER/: スニペットの終了を示す正規表現または OMIT マーカーのキーワード。 このディレクティブが処理される際に、指定されたGoファイルからマーカーで囲まれたコードが抽出され、HTMLドキュメントに埋め込まれます。
  4. image および image/draw パッケージ: Go言語の標準ライブラリには、画像処理を行うための image パッケージと、画像を別の画像に描画するための image/draw パッケージがあります。

    • image.Point: 2次元空間における点の座標を表す構造体。
    • image.Image: 画像データを表すインターフェース。
    • color.Color: 色を表すインターフェース。 このコミットで修正されたコード例は、これらのパッケージを使用して円形のマスクを通して画像を描画する方法を示していました。

技術的詳細

このコミットの技術的な詳細は、Goドキュメントシステムにおける {{code}} ディレクティブと OMIT マーカーの連携の誤用、およびその修正方法に集約されます。

元の状態では、doc/articles/image_draw.html は以下のように記述されていました。

{{code "/doc/progs/image_draw.go" `/CIRCLE/` `/STOP/`}}
{{code "/doc/progs/image_draw.go" `/CIRCLE2/` `/STOP/`}}

そして、doc/progs/image_draw.go の関連部分には、以下のようなマーカーがありました。

//CIRCLE OMIT
type circle struct {
	p image.Point
	r int
}
// ...
//STOP

ここで問題だったのは、image_draw.html の最初の {{code}} ディレクティブが /CIRCLE/ を開始マーカーとして指定している点です。image_draw.go 内では //CIRCLE OMITcircle 型の定義の直前に存在していました。しかし、この CIRCLE マーカーは、型定義だけでなく、その後の実際の描画ロジックを含むスニペットの開始としても意図されていました。

結果として、image_draw.html の最初の {{code}} ディレクティブは、//CIRCLE OMIT から //STOP までのブロック(つまり、circle 型の定義とそれに続く描画ロジック)を抽出していました。そして、2番目の {{code}} ディレクティブも、おそらく同じか非常に似た内容を抽出するように設定されていたため、ドキュメント上で同じコードスニペットが重複して表示されるという現象が発生していました。

このコミットの修正は、このマーカーの衝突と重複を解消することに焦点を当てています。

  1. doc/articles/image_draw.html の変更: 最初の {{code}} ディレクティブの開始マーカーを /CIRCLE/ から /CIRCLESTRUCT/ に変更しました。

    -{{code "/doc/progs/image_draw.go" `/CIRCLE/` `/STOP/`}}
    +{{code "/doc/progs/image_draw.go" `/CIRCLESTRUCT/` `/STOP/`}}
    

    これにより、このディレクティブが image_draw.go 内の異なる、より具体的なコードブロックを参照するようになります。

  2. doc/progs/image_draw.go の変更:

    • //CIRCLE OMIT//CIRCLESTRUCT OMIT に変更しました。
      -//CIRCLE OMIT
      +//CIRCLESTRUCT OMIT
      
      これは、image_draw.html での参照変更に対応するものです。これにより、CIRCLESTRUCT マーカーは circle 型の定義のみを指すようになります。
    • //STOP//STOP OMIT に変更しました。
      -//STOP
      +//STOP OMIT
      
      STOP マーカーに OMIT を追加することで、この行自体がドキュメントに表示されないようにしつつ、スニペットの終了点としての役割を維持します。これは、ドキュメント生成時のクリーンさを保つための一般的なプラクティスです。

これらの変更により、image_draw.html の最初の {{code}} ディレクティブは //CIRCLESTRUCT OMIT から //STOP OMIT までのブロック、つまり circle 型の定義のみを抽出し、2番目の {{code}} ディレクティブは別の(おそらく CIRCLE2 で始まる)描画ロジックのスニペットを抽出するようになります。結果として、型定義と描画ロジックがそれぞれ独立したスニペットとして正しく表示され、重複が解消されます。

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

このコミットでは、以下の2つのファイルが変更されています。

  1. doc/articles/image_draw.html
  2. doc/progs/image_draw.go

それぞれのファイルの変更内容は以下の通りです。

doc/articles/image_draw.html

--- a/doc/articles/image_draw.html
+++ b/doc/articles/image_draw.html
@@ -178,7 +178,7 @@ To draw an image through a circular mask with center <code>p</code> and radius
 <code>r</code>:
 </p>
 
-{{code "/doc/progs/image_draw.go" `/CIRCLE/` `/STOP/`}}
+{{code "/doc/progs/image_draw.go" `/CIRCLESTRUCT/` `/STOP/`}}
 {{code "/doc/progs/image_draw.go" `/CIRCLE2/` `/STOP/`}}
   
 <p>

doc/progs/image_draw.go

--- a/doc/progs/image_draw.go
+++ b/doc/progs/image_draw.go
@@ -117,7 +117,7 @@ func Glyph() {
 	// STOP OMIT
 }
 
-//CIRCLE OMIT
+//CIRCLESTRUCT OMIT
 type circle struct {
 	p image.Point
 	r int
@@ -139,4 +139,4 @@ func (c *circle) At(x, y int) color.Color {
 	return color.Alpha{0}\n
 }
 
-//STOP
+//STOP OMIT

コアとなるコードの解説

このコミットのコアとなる変更は、Goドキュメントシステムがコードスニペットを抽出する際に使用する「マーカー」の調整です。

  1. doc/articles/image_draw.html の変更: 変更前:

    {{code "/doc/progs/image_draw.go" `/CIRCLE/` `/STOP/`}}
    

    変更後:

    {{code "/doc/progs/image_draw.go" `/CIRCLESTRUCT/` `/STOP/`}}
    

    この変更は、HTMLドキュメントが doc/progs/image_draw.go からコードを抽出する際に、どの開始マーカーを探すかを指示しています。元々は /CIRCLE/ という正規表現で始まるブロックを探していましたが、これを /CIRCLESTRUCT/ に変更しました。これにより、HTMLファイルは image_draw.go 内の //CIRCLESTRUCT OMIT で始まる特定のコードブロックを正確に参照するようになります。

  2. doc/progs/image_draw.go の変更: 変更前:

    //CIRCLE OMIT
    type circle struct {
    	p image.Point
    	r int
    }
    // ...
    //STOP
    

    変更後:

    //CIRCLESTRUCT OMIT
    type circle struct {
    	p image.Point
    	r int
    }
    // ...
    //STOP OMIT
    
    • //CIRCLE OMIT から //CIRCLESTRUCT OMIT への変更: これは、image_draw.html での参照変更に対応するものです。CIRCLE という汎用的なマーカー名から CIRCLESTRUCT というより具体的な名前に変更することで、このマーカーが circle 型の構造体定義に特化していることを明確にしています。これにより、ドキュメントシステムが意図しないコードブロックを抽出するのを防ぎます。
    • //STOP から //STOP OMIT への変更: STOP マーカーに OMIT を追加することで、この行自体が最終的なドキュメントの出力に含まれないようにしています。OMIT マーカーは、ドキュメント生成時にその行をスキップするよう指示するため、これにより生成されるHTMLがよりクリーンになります。STOP はスニペットの終了を示すマーカーとしての機能は維持されます。

これらの変更の組み合わせにより、image_draw.htmlcircle 型の定義を正確に参照し、その後に続く別の {{code}} ディレクティブ(CIRCLE2 を参照しているもの)が、円の描画ロジックの別のスニペットを抽出するようになります。結果として、ドキュメント上で型定義と描画ロジックがそれぞれ独立した、重複のない形で表示されるようになり、読者にとってより分かりやすいコード例が提供されるようになりました。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメントのソースコード (特に doc ディレクトリ): https://github.com/golang/go/tree/master/doc
  • Go言語の OMIT マーカーに関する情報 (Goのテストやドキュメントにおけるコードスニペットの扱い): https://go.dev/blog/test-examples
  • Go言語の image および image/draw パッケージのドキュメント。
  • コミットメッセージと差分情報。
  • Go言語のドキュメント生成システムに関する一般的な知識。