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

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

このコミットは、Go言語のgoyaccツールに含まれるunitsプログラムのサンプルデータファイルであるsrc/cmd/yacc/units.txtに対する変更です。units.txtは、様々な単位間の換算レート、特に通貨の為替レートを定義するために使用されます。このファイルは、goyaccで生成されたパーサーが単位変換を行う際のデータソースとして機能します。

コミット

  • コミットハッシュ: bdf6a43e233bd7ef64dfbfa93d538efb934589db
  • 作者: Andrew Balholm andybalholm@gmail.com
  • コミット日時: 2012年8月29日(水) 10:06:37 -0700

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

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

元コミット内容

cmd/yacc/units.txt: fix exchange rates
        In the example "units" program for goyacc, the exchange rates were
        reciprocals of the correct amounts. Turn them right-side-up
        and update them to current figures.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/6495053

変更の背景

このコミットの背景には、goyaccのサンプルプログラムであるunitsが使用する為替レートデータsrc/cmd/yacc/units.txtに二つの問題があったことが挙げられます。

  1. 為替レートの逆数問題: 以前のunits.txtでは、為替レートが「正しい金額の逆数」として定義されていました。例えば、「1ドルが100円」であるべきところを、「1円が0.01ドル」のように、基準通貨と対象通貨の関係が逆になっていたと考えられます。これにより、unitsプログラムが正確な単位変換を提供できないという問題が発生していました。
  2. 為替レートの陳腐化: 為替レートは日々変動するものであり、units.txtに記載されていたレートは2009年9月10日時点のものでした。コミットが2012年8月29日に行われていることから、約3年近く前の古いデータが使われており、現実の為替レートと大きく乖離していました。

これらの問題を解決し、unitsプログラムが正確かつ最新の為替レート情報を提供できるようにするために、このコミットが作成されました。

前提知識の解説

goyacc

goyaccは、Go言語で書かれたYacc(Yet Another Compiler Compiler)の実装です。Yaccは、文法定義ファイル(通常.yまたは.yy拡張子を持つ)から、その文法を解析するためのパーサー(構文解析器)のソースコードを自動生成するツールです。コンパイラやインタプリタのフロントエンド、あるいは特定の入力形式を解析するツール(今回のunitsプログラムのようなもの)の開発に広く利用されます。goyaccは、Go言語の強力な並行処理機能や型システムを活用して、効率的で堅牢なパーサーを生成することを目的としています。

unitsプログラム

unitsプログラムは、Unix/Linuxシステムで一般的に利用されるコマンドラインツールであり、様々な単位間の変換を行うことができます。例えば、「10メートルは何フィートか?」や「5ガロンは何リットルか?」といった単位変換の計算を実行します。goyaccのサンプルとして提供されているunitsプログラムは、この機能の簡略版をGo言語で実装する例として機能します。src/cmd/yacc/units.txtファイルは、このunitsプログラムが単位変換のルールや為替レートを読み込むためのデータファイルです。

為替レートの表現と逆数

為替レートは、ある通貨を別の通貨に交換する際の比率を示します。通常、為替レートは「1単位の基準通貨が何単位の対象通貨に相当するか」という形で表現されます。例えば、「1 USD = 150 JPY」というレートは、1アメリカドルが150日本円に相当することを示します。

「逆数」とは、ある数xに対して1/xとなる数のことです。為替レートの文脈で「逆数」が問題となる場合、それは例えば「1 USD = 150 JPY」であるべきところを、「1 JPY = 1/150 USD (約0.0066 USD)」のように、基準通貨と対象通貨の関係が逆転して定義されていたことを意味します。これにより、ユーザーが「100ドルは何円か?」と尋ねた際に、プログラムが誤った計算結果を返すことになります。

技術的詳細

src/cmd/yacc/units.txtファイルは、unitsプログラムが単位変換ルールを解釈するためのプレーンテキストファイルです。このファイルは、各行が「単位名\t\t\t変換ルール」の形式で記述されており、為替レートもこの形式で定義されています。

変更前の為替レートの定義は、例えば以下のようになっていました。

argentinapeso           1 | 0.2595 $

これは、「1アルゼンチンペソが0.2595米ドルに相当する」と読めます。しかし、コミットメッセージが示唆するように、これが「正しい金額の逆数」であった場合、本来は「1米ドルが約3.85アルゼンチンペソ(1/0.2595)」であるべきところを、逆の関係で定義してしまっていたことになります。つまり、unitsプログラムが「Xアルゼンチンペソは何ドルか?」という計算を行う際に、X * 0.2595ではなく、X / 0.2595(またはX * (1/0.2595))と計算すべきだった、あるいは定義自体を「1ドルが何アルゼンチンペソか」という形式にすべきだった、という問題です。

このコミットでは、この逆数問題を修正するために、為替レートの定義形式を一部変更し、同時に最新のレートに更新しています。

変更後の為替レートの定義は、主に以下の二つの形式に分かれます。

  1. currency_name $ X:

    argentinapeso           $ 0.2160
    

    これは、「1アルゼンチンペソが0.2160米ドルに相当する」という直接的な表現に変わっています。以前の1 | X $形式から$ X形式への変更は、unitsプログラムが為替レートを解釈する際の内部ロジックに合わせて、より直感的な表現に統一されたことを示唆しています。これにより、unitsプログラムは「Xアルゼンチンペソは何ドルか?」という計算をX * 0.2160として正しく実行できるようになります。

  2. currency_name $ 1 | Y:

    chilepeso               $ 1 | 480.6
    

    これは、「1米ドルが480.6チリペソに相当する」という形式です。この形式は、特に米ドルに対して価値が低い通貨(例:日本円、チリペソ、コロンビアペソなど)で用いられています。これは、unitsプログラムが「Xチリペソは何ドルか?」という計算をX / 480.6として実行することを意図していると考えられます。つまり、1 | Yは「Y単位の対象通貨が1単位の基準通貨(この場合は米ドル)に相当する」という関係を示しています。

為替レートの更新は、ファイル内の日付が2009年9月10日から2012年8月29日に変更されていることからも明らかです。これにより、unitsプログラムはより現実の為替レートに基づいて単位変換を行うことができるようになりました。

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

このコミットは、src/cmd/yacc/units.txtファイルのみを変更しています。変更の大部分は、為替レートの数値と表現形式の修正です。

--- a/src/cmd/yacc/units.txt
+++ b/src/cmd/yacc/units.txt
@@ -215,58 +215,58 @@ lumen			cd sr
 lux			cd sr/m²
 
 / MONEY DATE
-/ Thu Sep 10 2009
+\n/ Wed Aug 29, 2012
 
-argentinapeso			1 | 0.2595 $
-australiadollar			1 | 0.8618 $
-boliviaboliviano		1 | 0.1425 $
-brazilreal			1 | 0.5522 $
-britainpound			1 | 1.6651 $
-canadadollar			1 | 0.9277 $
-chilepeso			1 | 0.0018 $
-chinayuan			1 | 0.1464 $
-colombiapeso			1 | 0.0005 $
-czechkoruna			1 | 0.0572 $
-denmarkkrone			1 | 0.1958 $
-dominicanpeso			1 | 0.0278 $
-egyptpound			1 | 0.181 $
-elsalvadorcolon			1 | 0.1143 $
-europeuro			1 | 1.4577 $
-guatemalaquetzal		1 | 0.121 $
-honduraslempira			1 | 0.0529 $
-hongkongdollar			1 | 0.129 $
-hungaryforint			1 | 0.0054 $
-indiarupee			1 | 0.0207 $
-indonesiarupiah			1 | 0.0001 $
-israelshekel			1 | 0.2643 $
-japanyen			1 | 0.0109 $
-kenyashilling			1 | 0.0132 $
-kuwaitdinar			1 | 3.4854 $
-lebanonpound			1 | 0.0007 $
-malaysiaringgit			1 | 0.286 $
-mexicopeso			1 | 0.0748 $
-newzealanddollar		1 | 0.7028 $
-nicaraguacordoba		1 | 0.0487 $
-norwaykrone			1 | 0.1681 $
-pakistanrupee			1 | 0.0121 $
-paraguayguarani			1 | 0.0002 $
-perunewsol			1 | 0.3384 $
-philippinespeso			1 | 0.0207 $
-polandzloty			1 | 0.352 $
-russiaruble			1 | 0.0324 $
-saudiarabiariyal		1 | 0.2666 $
-singaporedollar			1 | 0.7018 $
-slovakkoruna			1 | 0.0484 $
-southafricarand			1 | 0.132 $
-southkoreawon			1 | 0.0008 $
-swedenkrona			1 | 0.1429 $
-switzerlandfranc		1 | 0.9627 $
-taiwandollar			1 | 0.0306 $
-thailandbaht			1 | 0.0294 $
-turkeynewlira			1 | 0.6678 $
-uaedirham			1 | 0.2722 $
-uruguaynewpeso			1 | 0.0451 $
-vietnamdong			1 | 0.0001 $
+argentinapeso			$ 0.2160
+australiadollar			$ 1.0372
+boliviaboliviano		$ 0.1427
+brazilreal			$ 0.4872
+britainpound			$ 1.5843
+canadadollar			$ 1.0117
+chilepeso			$ 1 | 480.6
+chinayuan			$ 0.1574
+colombiapeso			$ 1 | 1834
+czechkoruna			$ 0.0506
+denmarkkrone			$ 0.1681
+dominicanpeso			$ 0.0256
+egyptpound			$ 0.1640
+elsalvadorcolon			$ 1 | 8.75
+europeuro			$ 1.2528
+guatemalaquetzal		$ 0.1290
+honduraslempira			$ 0.0511
+hongkongdollar			$ 0.1289
+hungaryforint			$ 1 | 226.5
+indiarupee			$ 0.0180
+indonesiarupiah			$ 1 | 9540
+israelshekel			$ 0.2479
+japanyen			$ 0.0127
+kenyashilling			$ 0.0119
+kuwaitdinar			$ 3.5456
+lebanonpound			$ 1 | 1505.5
+malaysiaringgit			$ 0.3204
+mexicopeso			$ 0.0754
+newzealanddollar		$ 0.8035
+nicaraguacordoba		$ 0.0421
+norwaykrone			$ 0.1717
+pakistanrupee			$ 0.0106
+paraguayguarani			$ 1 | 4415
+perunewsol			$ 0.3832
+philippinespeso			$ 0.0236
+polandzloty			$ 0.3001
+russiaruble			$ 0.0311
+saudiarabiariyal		$ 1 | 3.75
+singaporedollar			$ 0.7976
+slovakkoruna			1 | 30.126 europeuro
+southafricarand			$ 0.1188
+southkoreawon			$ 1 | 1135
+swedenkrona			$ 0.1502
+switzerlandfranc		$ 1.0431
+taiwandollar			$ 0.0334
+thailandbaht			$ 0.0319
+turkeynewlira			$ 0.5504
+uaedirham			$ 0.2723
+uruguaynewpeso			$ 0.0465
+vietnamdong			$ 1 | 20865

主な変更点は以下の通りです。

  • 日付の更新: / MONEY DATE の下の行が Thu Sep 10 2009 から Wed Aug 29, 2012 に変更されています。
  • 為替レートの数値の更新: 各通貨の為替レートの数値が、2009年9月10日時点のものから2012年8月29日時点のものに更新されています。
  • 為替レートの表現形式の変更:
    • 多くの通貨で、1 | X $ の形式が $ X に変更されています。これは、1単位の当該通貨が何米ドルに相当するかを直接的に示す形式です。
    • 一部の通貨(チリペソ、コロンビアペソ、ハンガリーフォリント、インドネシアルピア、レバノンポンド、パラグアイグアラニー、サウジアラビアリヤル、韓国ウォン、ベトナムドンなど)では、1 | X $ の形式が $ 1 | Y に変更されています。これは、1米ドルが何単位の当該通貨に相当するかを示す形式です。
    • スロバキアコルナの行は、1 | 0.0484 $ から 1 | 30.126 europeuro に変更されており、米ドル基準からユーロ基準への変換が追加されています。

コアとなるコードの解説

このコミット自体はGo言語のコードを変更しているわけではなく、goyaccのサンプルプログラムが利用するデータファイルを変更しています。しかし、このデータファイルの変更は、unitsプログラムの動作に直接的な影響を与えます。

unitsプログラムは、units.txtファイルを読み込み、そこに定義された単位変換ルールや為替レートを内部的に解析して利用します。

  • 1 | X $ から $ X への変更: 以前の1 | X $という形式は、unitsプログラムのパーサーが為替レートを解釈する際に、誤った計算ロジックを適用していた可能性を示唆しています。例えば、1 | 0.2595 $が「1アルゼンチンペソは0.2595ドル」を意味すると解釈され、ユーザーが「100アルゼンチンペソは何ドルか?」と尋ねた際に100 * 0.2595と計算されるべきところ、もしこれが逆数として扱われていた場合、100 / 0.2595と計算されてしまっていたかもしれません。 新しい$ X形式は、より明確に「1単位の通貨がXドルに相当する」という関係を示しており、unitsプログラムがこの値を乗算係数として直接使用することで、正しい変換結果を得られるように設計されたと考えられます。

  • $ 1 | Y 形式の導入: この形式は、特に米ドルに対して価値が低い通貨(例:日本円)でよく見られる「1ドルが何円か」という表現に対応しています。$ 1 | Yは、「Y単位の当該通貨が1米ドルに相当する」ことを意味します。unitsプログラムは、この形式を読み込むことで、例えば「X日本円は何ドルか?」という計算をX / Yとして実行できるようになります。これは、為替レートの表現方法として一般的であり、unitsプログラムがより柔軟な為替レートの定義に対応できるようになったことを示しています。

  • 為替レートの更新: 為替レートの数値が更新されたことで、unitsプログラムは、より現実の経済状況に即した正確な単位変換を提供できるようになりました。古いデータを使用し続けることは、特に金融関連の計算において、誤った結果を導き出すリスクを伴います。

このコミットは、unitsプログラムの正確性と実用性を向上させるための重要なデータ更新であり、goyaccのサンプルとしての価値を高めるものです。

関連リンク

  • Go言語公式サイト: https://go.dev/
  • Go言語のcmd/yaccパッケージのドキュメント (もし存在すれば): Goの標準ライブラリにはyaccパッケージは直接含まれていませんが、goyaccツール自体はGoのツールチェインの一部として提供されることがあります。具体的なドキュメントはgoyaccのソースコードリポジトリや関連するGoのドキュメントで確認できます。
  • Yacc (Wikipedia): https://ja.wikipedia.org/wiki/Yacc
  • units (Unix command) (Wikipedia): https://en.wikipedia.org/wiki/Units_(Unix_command)

参考にした情報源リンク

  • GitHubコミットページ: https://github.com/golang/go/commit/bdf6a43e233bd7ef64dfbfa93d538efb934589db
  • Go言語のソースコードリポジトリ: src/cmd/yacc/units.txtのコンテキストを理解するために参照しました。
  • 一般的な為替レートの概念と表現方法に関する情報: 為替レートの逆数問題や表現形式の理解に役立ちました。
  • 2009年および2012年頃の歴史的な為替レートデータ: 為替レートの更新が妥当であるかを確認するために参照しました。