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

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

このコミットは、Go言語の公式ドキュメントツールであるgodocのウェブインターフェースに組み込まれているGo Playgroundウィジェットにおいて、「おもちゃ」(toy)と呼ばれる事前定義されたコード例を選択する機能を復元するものです。具体的には、ユーザーがドロップダウンメニューからGoのコード例を選択し、それをPlaygroundに読み込んで実行できるようにする機能が修正されています。

コミット

  • コミットハッシュ: bd31e62982461b9b5b10b8c2181eff56fe4085f9
  • 作者: Andrew Gerrand adg@golang.org
  • コミット日時: 2012年10月11日 木曜日 09:53:37 +1100
  • 変更ファイル:
    • doc/play/playground.js
    • doc/root.html

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

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

元コミット内容

godoc: restore toy selection to playground widget

Fixes #4225.

R=golang-dev
CC=golang-dev
https://golang.org/cl/6640054

変更の背景

このコミットの目的は、godocのGo Playgroundウィジェットから失われていた「おもちゃ」(toy)選択機能を復元することです。コミットメッセージにある「restore」という言葉と「Fixes #4225」という記述から、以前は存在していたこの機能が何らかの理由で動作しなくなっていたか、削除されていたことが推測されます。Issue #4225は、この機能の不具合や欠如を報告していたものと考えられます。

「おもちゃ」機能は、ユーザーがGo PlaygroundでGo言語の様々な機能やライブラリの動作を簡単に試せるように、あらかじめ用意されたコード例(例えば、特定のパッケージの使用例やアルゴリズムの実装例など)を提供します。これにより、ユーザーは手動でコードを入力する手間を省き、迅速にGo言語の挙動を学習・確認することができます。この機能が失われたことでユーザー体験が損なわれていたため、本コミットでその利便性を回復することが図られました。

前提知識の解説

Go Playground

Go Playgroundは、Go言語のプログラムをウェブブラウザ上で実行できるサンドボックス環境を提供するサービスです。go.devなどの公式ウェブサイトや、godocのウェブインターフェースに組み込まれて利用されます。ユーザーはGoのコードを記述し、「Run」ボタンをクリックすることで、サーバーサイドでそのコードがコンパイル・実行され、結果がブラウザに表示されます。これにより、Go言語の学習や簡単なコードのテストを、ローカル環境のセットアップなしに行うことができます。

godoc

godocは、Go言語のソースコードからドキュメントを生成するためのツールです。Goのパッケージ、関数、型、変数などの定義とコメントを解析し、HTML形式のドキュメントとして出力します。また、godoc -httpコマンドを使用することで、ローカルにドキュメントサーバーを立ち上げることができます。このサーバーは、Goの標準ライブラリやユーザーが作成したパッケージのドキュメントをブラウザで閲覧可能にするだけでなく、-playフラグを付与することで、ドキュメント内のコード例をGo Playgroundで実行できる機能(Playgroundウィジェット)を提供します。

AJAX (Asynchronous JavaScript and XML)

AJAXは、ウェブページ全体をリロードすることなく、非同期でサーバーとデータをやり取りするための技術の総称です。JavaScriptのXMLHttpRequestオブジェクト(またはfetch API)を使用して、バックグラウンドでサーバーにリクエストを送信し、レスポンスを受け取ります。これにより、ウェブアプリケーションはよりインタラクティブで応答性の高いユーザーインターフェースを提供できます。本コミットでは、ユーザーが「おもちゃ」を選択した際に、そのコード内容をサーバーから非同期で取得するためにAJAXが利用されています。

HTML select要素とJavaScriptイベントハンドリング

HTMLの<select>要素は、ドロップダウンリストを作成するために使用されます。ユーザーはこのリストから一つのオプションを選択できます。JavaScriptでは、この<select>要素に対してchangeイベントリスナーを登録することができます。ユーザーがドロップダウンリストの選択を変更すると、このchangeイベントが発火し、登録されたJavaScript関数が実行されます。本コミットでは、このメカニズムを利用して、ユーザーが「おもちゃ」を選択したときに、対応するGoコードをPlaygroundに読み込む処理をトリガーしています。

jQuery

変更されたplayground.jsファイル内の$記号は、JavaScriptライブラリであるjQueryが使用されていることを示唆しています。jQueryは、HTMLドキュメントの走査、イベントハンドリング、アニメーション、AJAXなどの操作を、より簡単かつクロスブラウザ互換性のある方法で記述できるようにするライブラリです。

技術的詳細

このコミットの主要な変更は、doc/play/playground.jsに「おもちゃ」選択機能のロジックを追加し、doc/root.htmlから関連する古い設定を削除することです。

playground.jsは、Go Playgroundウィジェットのクライアントサイドの動作を制御するJavaScriptファイルです。このファイルは、Playgroundの初期化時に渡されるoptsオブジェクトを通じて、コードエディタ、出力表示エリア、実行ボタンなどのHTML要素への参照を受け取ります。

本コミットでは、optsオブジェクトに新たにtoysElというオプションが追加されました。これは、ユーザーが「おもちゃ」を選択するためのHTMLの<select>要素への参照を期待します。

追加されたJavaScriptコードは、以下のロジックを実装しています。

  1. opts['toysEl']が存在するか(つまり、toysElオプションが渡されているか)を確認します。
  2. もしtoysElが存在すれば、その要素に対してchangeイベントリスナーをバインドします。
  3. ユーザーがtoysEl(ドロップダウンリスト)の選択を変更すると、changeイベントが発火し、以下の処理が実行されます。 a. 選択された「おもちゃ」の値(例: hello.go)を取得します。 b. jQueryの$.ajax関数を使用して、サーバーに対して非同期HTTP GETリクエストを送信します。リクエストのURLは、選択された「おもちゃ」の値に基づいて動的に構築されます(例: /doc/play/hello.go)。 c. サーバーからのレスポンスが完了すると、completeコールバック関数が実行されます。 d. HTTPステータスコードが200(成功)であれば、レスポンスのテキスト(Goコードの内容)をsetBody関数に渡して、Playgroundのコードエディタの内容を更新します。 e. ステータスコードが200以外であれば、「Server error; try again.」というアラートメッセージを表示します。

一方、doc/root.htmlからは、以下の変更が行われました。

  1. <script type="text/javascript" src="/doc/play/playground.js"></script>という行が削除されました。これは、playground.jsroot.htmlに直接インクルードされなくなったことを意味します。しかし、playground関数は引き続きroot.html内で呼び出されているため、playground.jsは別のメカニズム(例えば、別のJavaScriptファイルからの動的ロードや、ビルドプロセスによるバンドルなど)でロードされることが前提となっていると考えられます。
  2. playground関数の初期化オプションから"simple": true,が削除されました。これは、おそらく「おもちゃ」選択機能の導入により、以前の「シンプル」モードが不要になったか、あるいは「おもちゃ」機能がその役割を包含するようになったためと考えられます。

これらの変更により、godocのウェブインターフェースに表示されるGo Playgroundは、ユーザーが簡単にGoのコード例を読み込み、実行できる機能を取り戻しました。

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

diff --git a/doc/play/playground.js b/doc/play/playground.js
index 3f766a9bf1..0f56fc0564 100644
--- a/doc/play/playground.js
+++ b/doc/play/playground.js
@@ -3,13 +3,14 @@
 // license that can be found in the LICENSE file.\n \n // opts is an object with these keys\n-// \tcodeEl - code editor element\n-// \toutputEl - program output element\n+//\tcodeEl - code editor element\n+//\toutputEl - program output element\n //\trunEl - run button element\n-// \tfmtEl - fmt button element (optional)\n-// \tshareEl - share button element (optional)\n-// \tshareURLEl - share URL text input element (optional)\n-// \tshareRedirect - base URL to redirect to on share (optional)\n+//\tfmtEl - fmt button element (optional)\n+//\tshareEl - share button element (optional)\n+//\tshareURLEl - share URL text input element (optional)\n+//\tshareRedirect - base URL to redirect to on share (optional)\n+//\ttoysEl - toys select element (optional)\n //\tenableHistory - enable using HTML5 history API (optional)\n function playground(opts) {\n \tvar code = $(opts[\'codeEl\']);\n@@ -226,4 +227,21 @@ function playground(opts) {\n \t\t\t});\n \t\t});\n \t}\n+\n+\tif (opts[\'toysEl\'] != null) {\n+\t\t$(opts[\'toysEl\']).bind(\'change\', function() {\n+\t\t\tvar toy = $(this).val();\n+\t\t\t$.ajax(\"/doc/play/\"+toy, {\n+\t\t\t\tprocessData: false,\n+\t\t\t\ttype: \"GET\",\n+\t\t\t\tcomplete: function(xhr) {\n+\t\t\t\t\tif (xhr.status != 200) {\n+\t\t\t\t\t\talert(\"Server error; try again.\")\n+\t\t\t\t\t\treturn;\n+\t\t\t\t\t}\n+\t\t\t\t\tsetBody(xhr.responseText);\n+\t\t\t\t}\n+\t\t\t});\n+\t\t});\n+\t}\n }\ndiff --git a/doc/root.html b/doc/root.html
index 3b4b43a5e0..cc2bfd1ba9 100644
--- a/doc/root.html
+++ b/doc/root.html
@@ -85,7 +85,6 @@ Linux, Mac OS X, Windows, and more.\n <div style=\"clear: both;\"></div>\n \n <script type=\"text/javascript\" src=\"https://www.google.com/jsapi\"></script>\n-<script type=\"text/javascript\" src=\"/doc/play/playground.js\"></script>\n <script type=\"text/javascript\">\n google.load(\"feeds\", \"1\");\n \n@@ -122,7 +121,6 @@ function init() {\n \n \t// Set up playground.\n \tplayground({\n-\t\t\"simple\":        true,\n \t\t\"codeEl\":        \"#learn .code\",\n \t\t\"outputEl\":      \"#learn .output\",\n \t\t\"runEl\":         \"#learn .run\",\n```

## コアとなるコードの解説

### `doc/play/playground.js` の変更点

1.  **`opts` オブジェクトのドキュメント更新**:
    `// opts is an object with these keys` のコメントブロックに、新しく `//\ttoysEl - toys select element (optional)` が追加されました。これは、`playground` 関数が初期化オプションとして `toysEl` というキーを受け取ることを明示しています。`toysEl` は、Go Playgroundに読み込む「おもちゃ」を選択するためのHTMLの`<select>`要素への参照を期待します。

2.  **「おもちゃ」選択機能のロジック追加**:
    ファイルの末尾に、以下の新しいコードブロックが追加されました。
    ```javascript
    if (opts['toysEl'] != null) {
        $(opts['toysEl']).bind('change', function() {
            var toy = $(this).val();
            $.ajax("/doc/play/"+toy, {
                processData: false,
                type: "GET",
                complete: function(xhr) {
                    if (xhr.status != 200) {
                        alert("Server error; try again.")
                        return;
                    }
                    setBody(xhr.responseText);
                }
            });
        });
    }
    ```
    -   `if (opts['toysEl'] != null)`: `playground` 関数が呼び出された際に、`toysEl` オプションが提供されているかどうかを確認します。これにより、この機能が必要な場合にのみコードが実行されます。
    -   `$(opts['toysEl']).bind('change', function() { ... });`: `toysEl` で指定されたHTML要素(おそらく`<select>`タグ)に対して、`change`イベントリスナーをバインドしています。ユーザーがドロップダウンリストの選択を変更すると、この関数が実行されます。
    -   `var toy = $(this).val();`: 選択されたオプションの`value`属性の値を取得し、`toy`変数に格納します。この値は、サーバーから取得するGoコードのファイル名(例: `hello.go`)に対応すると考えられます。
    -   `$.ajax("/doc/play/"+toy, { ... });`: jQueryの`$.ajax`関数を使用して、サーバーに非同期リクエストを送信します。
        -   `url`: `"/doc/play/"+toy` という形式で、選択された「おもちゃ」のGoコードを取得するためのURLを構築します。例えば、`toy`が`hello.go`であれば、`/doc/play/hello.go`にリクエストが送られます。
        -   `processData: false`: データ処理を行わない設定です。GETリクエストなので通常は不要ですが、明示的に指定されています。
        -   `type: "GET"`: HTTP GETメソッドでリクエストを送信することを指定します。
        -   `complete: function(xhr) { ... }`: リクエストが完了した際に実行されるコールバック関数です。`xhr`オブジェクトには、HTTPレスポンスに関する情報が含まれます。
            -   `if (xhr.status != 200)`: HTTPステータスコードが200(OK)以外の場合、サーバーエラーが発生したと判断し、`alert("Server error; try again.")`でユーザーにエラーメッセージを表示し、処理を中断します。
            -   `setBody(xhr.responseText);`: ステータスコードが200であれば、サーバーからのレスポンスボディ(取得したGoコードのテキスト)を`setBody`関数に渡します。`setBody`関数は、Playgroundのコードエディタの内容を更新する役割を担っていると推測されます。

### `doc/root.html` の変更点

1.  **`playground.js` のスクリプトタグ削除**:
    `<script type="text/javascript" src="/doc/play/playground.js"></script>` の行が削除されました。これは、`root.html`が直接`playground.js`を読み込まなくなったことを意味します。しかし、`root.html`の後半で`playground({...})`関数が引き続き呼び出されているため、`playground.js`は別の方法(例えば、別のJavaScriptファイルが依存関係として読み込む、またはビルドプロセスでバンドルされるなど)でロードされることが前提となっています。

2.  **`playground` 初期化オプションからの `"simple": true` 削除**:
    `playground` 関数の初期化ブロックから、`"simple": true,` の行が削除されました。
    ```diff
    -		"simple":        true,
    		"codeEl":        "#learn .code",
    		"outputEl":      "#learn .output",
    		"runEl":         "#learn .run",
    ```
    この`"simple": true`オプションの具体的な機能は不明ですが、「おもちゃ」選択機能の復元に伴い、その役割が不要になったか、あるいは「おもちゃ」機能がより包括的なコード例の提供方法として置き換わった可能性が考えられます。

これらの変更により、`godoc`のウェブインターフェースは、ユーザーがGo Playgroundで様々なGoコード例を簡単に試せるようになり、学習やデモンストレーションの利便性が向上しました。

## 関連リンク

-   GitHubコミットページ: [https://github.com/golang/go/commit/bd31e62982461b9b5b10b8c2181eff56fe4085f9](https://github.com/golang/go/commit/bd31e62982461b9b5b10b8c2181eff56fe4085f9)
-   Gerrit Change-ID: [https://golang.org/cl/6640054](https://golang.org/cl/6640054)

## 参考にした情報源リンク

-   Go Playground: [https://go.dev/play/](https://go.dev/play/)
-   godocコマンド: [https://go.dev/blog/godoc](https://go.dev/blog/godoc)
-   Go Testable Examples: [https://go.dev/blog/examples](https://go.dev/blog/examples)
-   Stack Overflow - How to enable Go Playground in godoc: [https://stackoverflow.com/questions/10900000/how-to-enable-go-playground-in-godoc](https://stackoverflow.com/questions/10900000/how-to-enable-go-playground-in-godoc)
-   JetBrains YouTrack - GO-4225 (Name starts with package name inspection optimization): [https://youtrack.jetbrains.com/issue/GO-4225](https://youtrack.jetbrains.com/issue/GO-4225) (コミットメッセージの`Fixes #4225`はGoプロジェクト内部のIssueトラッカーを参照している可能性が高いですが、一般的な検索で関連性の高い情報としてJetBrainsのGoLand IDEのIssueも確認しました。)
-   Google Search for "golang godoc playground widget"
-   Google Search for "golang issue 4225"
-   Google Search for "golang/go issue 4225"