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

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

このコミットは、Go言語の標準ライブラリにおけるHTMLパーサーのパッケージ構造に関する重要な変更を記録しています。具体的には、開発中のHTMLパーサーを html パッケージから exp/html パッケージへ移動させるものです。これは、Go 1のリリースに向けてAPIの安定性を確保するための戦略的な判断であり、パーサーのAPIがまだ確定していないため、実験的な位置付けとして exp ディレクトリに配置されました。既存の html パッケージは、EscapeStringUnescapeString の2つの関数のみを保持する形に変更されています。

コミット

  • Author: Nigel Tao nigeltao@golang.org
  • Date: Wed Jan 25 10:54:59 2012 +1100
  • Commit Hash: 324513bc5f1aa44685e547fec5e04fd0b2c8af40

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

https://github.com/golang/go/commit/324513bc5f1aa44685e547fec5e04fd0b2c8af40

元コミット内容

html: move the HTML parser to an exp/html package. The parser is a
work in progress, and we are not ready to freeze its API for Go 1.

Package html still exists, containing just two functions: EscapeString
and UnescapeString.

Both the packages at exp/html and html are "package html". The former
is a superset of the latter.

At some point in the future, the exp/html code will move back into
html, once we have finalized the parser API.

R=rsc, dsymonds
CC=golang-dev
https://golang.org/cl/5571059

変更の背景

この変更の主な背景には、Go言語のバージョン1(Go 1)のリリースに向けたAPIの安定性への強いコミットメントがあります。Go 1は、Go言語の長期的な互換性を保証するための重要なマイルストーンとして位置づけられていました。一度Go 1の標準ライブラリに含まれたAPIは、将来のバージョンでも後方互換性が維持されることが約束されており、これはGoエコシステム全体の安定性と信頼性を築く上で極めて重要でした。

HTMLパーサーはウェブアプリケーション開発において非常に重要なコンポーネントですが、そのAPI設計は複雑であり、当時の開発段階ではまだ試行錯誤が続いていました。Goチームは、未成熟なAPIをGo 1の安定版に含めることで、将来的に互換性のない変更を余儀なくされるリスクを避けたいと考えました。

そこで、このコミットでは、HTMLパーサーを html パッケージから exp/html (experimental HTML) パッケージへと移動させるという決定がなされました。exp ディレクトリは、Goの標準ライブラリにおいて、まだAPIが安定しておらず、将来的に変更される可能性がある実験的なパッケージを配置するための特別な場所です。これにより、開発者はパーサーの機能を試すことができますが、そのAPIがGo 1の互換性保証の対象外であることを明確に示しています。

前提知識の解説

  1. Go言語のパッケージシステム: Go言語は、コードのモジュール化と再利用のためにパッケージシステムを採用しています。各Goファイルは package 宣言を持ち、関連する機能がまとめられています。パッケージはディレクトリ構造に対応し、import 文で他のパッケージの機能を利用できます。
  2. Go 1の互換性保証: Go 1は、Go言語の歴史において非常に重要なリリースでした。このリリース以降、Goチームは「Go 1の互換性保証 (Go 1 Compatibility Guarantee)」を掲げ、Go 1で公開されたAPIは、特別な理由がない限り、将来のGoのバージョンでも後方互換性が維持されることを約束しました。これにより、Goで書かれたプログラムが将来のGoバージョンでも動作し続けることが保証され、開発者は安心してライブラリやアプリケーションを構築できるようになりました。
  3. exp ディレクトリ: Goの標準ライブラリには、exp という特別なディレクトリが存在します。このディレクトリに配置されたパッケージは「実験的 (experimental)」と見なされ、そのAPIはGo 1の互換性保証の対象外です。つまり、これらのパッケージのAPIは、将来のGoのバージョンで予告なく変更されたり、削除されたりする可能性があります。これは、新しいアイデアや機能が標準ライブラリに組み込まれる前に、コミュニティからのフィードバックを得つつ、API設計を洗練させるためのメカニズムとして機能します。
  4. HTMLパーサー: HTMLパーサーは、HTMLドキュメントを読み込み、その構造を解析して、プログラムが扱えるデータ構造(通常はDOMツリー)に変換するソフトウェアコンポーネメントです。ウェブブラウザ、スクレイピングツール、HTMLテンプレートエンジンなど、様々なアプリケーションで利用されます。HTMLは非常に柔軟な(そして時に不完全な)構文を持つため、堅牢なHTMLパーサーを実装することは複雑な作業です。
  5. HTMLエンティティ: HTMLエンティティは、HTMLドキュメント内で特殊文字(例: <>&)や、キーボードから直接入力できない文字(例: ©)を表現するための仕組みです。&amp;&)、&lt;<)、&gt;>)、&quot;")、&apos;')などの名前付きエンティティや、&#xNNNN;(16進数)や &#NNNN;(10進数)のような数値文字参照があります。

技術的詳細

このコミットの技術的な核心は、Goのパッケージ管理とAPIの進化戦略にあります。

  1. パッケージの移動とリネーム:

    • src/pkg/html ディレクトリにあったHTMLパーサー関連のファイル群が、src/pkg/exp/html ディレクトリに移動されました。これは、ファイルパスの変更だけでなく、Goのビルドシステムにおけるパッケージの参照パスも変更されることを意味します。
    • コミットメッセージにある src/pkg/{ => exp}/html/ という表記は、Gitの差分表示でディレクトリのリネームを示しています。
    • Makefile の変更 (src/pkg/Makefilesrc/pkg/exp/html/Makefile) は、新しい exp/html パッケージがビルドシステムに認識されるようにするためのものです。
  2. パッケージ名の重複と共存:

    • 興味深いのは、移動後の exp/html パッケージも、元の html パッケージも、どちらも package html と宣言されている点です。これは、Goのパッケージ名がディレクトリ名と必ずしも一致する必要がないことを示しています(ただし、慣習的には一致させることが推奨されます)。
    • これにより、exp/html パッケージは html パッケージの「スーパーセット」として機能します。つまり、exp/html をインポートするコードは、パーサー機能を含む完全なHTML処理機能を利用でき、一方、html パッケージをインポートするコードは、EscapeStringUnescapeString の基本的な文字列エスケープ機能のみを利用できます。
  3. APIの段階的導入:

    • この戦略は、Go 1のリリース前に、まだAPIが固まっていない機能を標準ライブラリに含めるための一般的なパターンでした。exp ディレクトリに置くことで、GoチームはAPIを自由に反復・改善でき、ユーザーは不安定なAPIに依存することなく、安定したGo 1のリリースを待つことができます。
    • コミットメッセージにある「At some point in the future, the exp/html code will move back into html, once we have finalized the parser API.」という記述は、将来的にパーサーAPIが安定したと判断された場合、exp/html の内容が再び html パッケージに統合される計画があることを示しています。これは、Goの標準ライブラリがどのように進化していくかを示す良い例です。
  4. entity.go の追加:

    • src/pkg/exp/html/entity.go は、このコミットで新規追加されたファイルの中で最も大きなものです。このファイルは、HTML5で定義されている膨大な数の名前付き文字参照(HTMLエンティティ)とその対応するUnicodeルーン(文字)のマッピングを定義しています。
    • HTMLパーサーが正しく機能するためには、&amp;&copy; のようなエンティティを対応する文字に変換する機能が不可欠です。このファイルは、その変換ロジックの基盤となるデータを提供します。

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

このコミットにおけるコアとなるコードの変更は、主に以下のファイル移動と新規ファイルの追加です。

  • src/pkg/Makefile:
    • exp/html が新しいディレクトリとして DIRS リストに追加され、ビルドシステムがこの新しい実験的パッケージを認識するように変更されました。
  • src/pkg/exp/html/Makefile (新規):
    • exp/html パッケージのビルド設定ファイルが新規作成されました。このファイルは、パッケージ名 (TARG=html) と、このパッケージに含まれるGoソースファイル (GOFILES) のリストを定義しています。
  • src/pkg/{ => exp}/html/const.go など多数のファイル (リネーム):
    • src/pkg/html/ ディレクトリにあった既存のHTMLパーサー関連のGoソースファイル(const.go, doc.go, doctype.go, foreign.go, node.go, parse.go, render.go, token.go および関連するテストファイルやテストデータ)が、src/pkg/exp/html/ ディレクトリに移動されました。Gitの差分では similarity index 100% と表示されており、ファイルの内容自体は変更されていないことを示します。
  • src/pkg/exp/html/entity.go (新規):
    • HTMLエンティティとUnicodeルーンのマッピングを定義する、非常に大きなファイルが新規追加されました。
  • src/pkg/exp/html/entity_test.go (新規):
    • entity.go で定義されたエンティティマッピングのテストファイルが新規追加されました。
  • src/pkg/exp/html/escape.go (新規):
    • HTMLエスケープ/アンエスケープ処理を実装するファイルが新規追加されました。
  • src/pkg/html/Makefile (変更):
    • 元の html パッケージの Makefile から、パーサー関連のファイルが削除されました。
  • src/pkg/html/escape.go (変更):
    • 元の html パッケージの escape.go が変更され、EscapeStringUnescapeString の2つの関数のみが残るように簡素化されました。

コアとなるコードの解説

このコミットの主要なコード変更は、HTMLパーサーの機能が exp/html に移管されたこと、そして entity.goescape.go という重要な新しいファイルが導入されたことです。

  1. exp/html/entity.go:

    • このファイルは、HTMLパーサーがHTMLエンティティを正しく解釈するために不可欠なデータを提供します。
    • 内部的には、entity という map[string]rune 型の変数(Goのマップ型)が定義されており、キーにはHTMLエンティティ名(例: "amp;""nbsp;")、値にはそれに対応するUnicodeのルーン(文字コード)が格納されています。
    • 例えば、"amp;"'\U00000026' (Unicodeの & 文字) に、"COPY;"'\U000000A9' (Unicodeの © 文字) にマッピングされています。
    • このマップは、HTML5の仕様に準拠した広範なエンティティリストを含んでおり、パーサーがHTMLドキュメント内のエンティティを効率的に実際の文字に変換できるようにします。
  2. exp/html/escape.go:

    • このファイルは、HTMLの特殊文字をエスケープ(例: <&lt; に変換)したり、エスケープされた文字をアンエスケープ(例: &gt;> に変換)したりする機能を提供します。
    • HTMLコンテンツを安全にウェブページに表示したり、ユーザー入力からHTMLタグを無効化したりする際に不可欠な機能です。
    • 元の html パッケージにも EscapeStringUnescapeString が残されていますが、exp/htmlescape.go はパーサー内部でより詳細な制御や、将来的な拡張性を考慮した実装を含んでいる可能性があります。
  3. パーサーのコアロジック (parse.go, token.go, render.go など):

    • これらのファイルは、HTMLドキュメントの字句解析(トークン化)、構文解析(DOMツリー構築)、そしてDOMツリーからHTML文字列へのレンダリングといった、HTMLパーサーの主要な機能を実装しています。
    • exp ディレクトリへの移動により、これらのAPIはGo 1の安定版とは別に、継続的に開発・改善されることになりました。

この変更により、Go言語のHTML処理機能は、APIの安定性を損なうことなく、より堅牢で機能豊富なパーサーへと進化するための道筋がつけられました。

関連リンク

参考にした情報源リンク