パッケージ

要約:
  • パッケージには、グローバル変数、定数、プロシージャ、テキスト形式、列挙型、およびクラスの定義が格納されます。
  • パッケージは、1 つのファイルで構成される場合と複数のファイルで構成される場合があります。
  • パッケージが複数ファイルで構成されている場合、1 つのメイン ファイルがパッケージを定義し、include を使用して付属ファイルを追加します。
  • パッケージを使用するには、メイン ファイルをロードします。

概要

パッケージには通常、論理的にまとめられたコード群が格納されます。たとえば、三角関数用パッケージ、ビット演算関数用パッケージ、科学計算関数用パッケージなどを作成できます。パッケージにコードを格納すると、Curl® 言語で書かれた 1 つ以上のアプレットまたは他のパッケージに、コードを簡単にインポートできます。
パッケージにはコードの定義、グローバル変数、定数、プロシージャ、テキスト形式、マクロ、クラス、および列挙型の定義が格納されます。アプレットやパッケージは別のパッケージをインポートし、そのインポートされたパッケージに格納されていた定義を使うことができます。
Curl® 実行環境 が作動しているインターネット ブラウザでパッケージ ファイルを表示することはできません。ブラウザでパッケージ ファイルを表示しようとすると、Cuyl RTE は、パッケージをブラウズできないことを示すエラー メッセージを表示します。表示できるのは Curl アプレットだけです。
パッケージの内容が評価されるプロセスは、アプレットの評価プロセスとは異なります。1 回の処理でパッケージ内の定義がメモリにインポートされます。定義は一度にインポートされるので、前方参照も循環参照も可能です。例えば、パッケージの中のプロシージャは、パッケージで後に宣言されたグローバル変数を使用することが出来ます。しかし、トップレベルの変数は、パッケージ中に出現する順に初期化されます。そのため、初期化される前にその変数を参照しないようにする必要があります。
パッケージは、1 つのファイルで構成される場合と複数のファイルで構成される場合があります。パッケージが複数ファイルで構成されている場合、1 のメイン ファイルと複数の付属ファイルがあります。パッケージ定義はメイン ファイルに記述されています。
パッケージを論理的にグループ化できるようにするため、Curl 言語ではスーパーパッケージもサポートされています。スーパーパッケージとは、複数のパッケージまたは他のスーパーパッケージをパブリックにインポートするファイルのことです。たとえば、スーパーパッケージを使ってすべての数学計算パッケージをグループ化できます。互いに関連のある複数のパッケージをスーパーパッケージにグループ化すれば、それらの関連パッケージすべてをアプレットにインポートする際、パッケージごとに import 式を記述する必要がありません。

パッケージ ファイルの作成

パッケージ ファイルの構文を次に示します。
構文:herald
package-declaration
[import-expressions]
[include-expressions]
[content]
説明:
heraldヘラルド。Curl® API のバージョンおよびコンテンツの種類を示します。詳細については、「ヘラルド」を参照してください。
package-declarationパッケージ宣言。このファイルがメインのパッケージ ファイルであることを示します。詳細については、「パッケージ宣言」を参照してください。
import-expressionsimport 式 (オプション)。import 式は、他のパッケージ内の定義を現在のファイルにインポートします。詳細については、「import 式」を参照してください。
include-expressionsオプションの include 式。include 式は、その他のファイルからの定義をパッケージファイルに追加します。
contentCurl 言語で記述された定義で構成されます。
この構文では、コメントおよび空白行は無視されます。つまり、コメントや空白行はこのファイル内の任意の位置に記述できます。次のコードは、シンプルな Curl 言語パッケージの例です。このパッケージの先頭にはコメントがあり、その次にヘラルドがあります。このヘラルドは、このパッケージを評価するのに必要な Curl API を示しています。その下のパッケージ宣言は、このファイルが COM.CURL.MATH.TRIG パッケージに対するメイン ファイルであることを示しています。このパッケージ宣言には、パッケージに関するメタデータも含まれています。その後にパッケージ内のさまざまな定義が続きます。
|| File:     trig/load.scurl
|| Contents: The Curl language's package of trigonometric functions.
|| Author:   Joe Soap

{curl 8.0 package}

{package COM.CURL.MATH.TRIG,
    author = "Joe Soap",
    copyright = "Copyright (c) 1998-2011, SCSK Corporation.",
    version = "1.0"
}

|| Definitions for trigonometric functions.
...

パッケージ宣言

パッケージ宣言は、そのファイルがメインのパッケージ ファイルであることを示します。パッケージ宣言を指定するには、package 式を使います。package 式は、ヘラルドの直後の行 (コマンドや空白行は数えない) に記述します。package 式は、パッケージ名を定義し、またパッケージに関するメタ情報を示します。package 式で付属パッケージ ファイルを指定することもできます。package 式の構文を次に示します。
構文:{package name[, meta-data-list]}
説明:
nameパッケージ名。詳細については、「パッケージの命名」を参照してください。
meta-data-listこのファイルに対するメタデータ。詳細については、「メタデータ」を参照してください。
次の package 式は、COM.CURL.MATH.TRIG パッケージに対するメインのパッケージ ファイルであることを示しています。
{package COM.CURL.MATH.TRIG,
    author="Joe Soap",
    version="1.0"
}
{include
    "sin.curl",
    "cos.curl",
    "tan.curl"
}

パッケージの命名

パッケージ宣言ではパッケージの名前を定義します。パッケージ名は、1 つ以上の有効な Curl 言語識別子で構成します。識別子が複数個ある場合はドットで区切ります。パッケージ名は Curl 言語の命名規則に従っている必要があります。Curl 言語の命名規則では、パッケージ名には大文字しか使用できません。たとえば三角関数を含むパッケージに対して、次のような名前を指定できます。
場合によっては、パッケージの階層情報を表すパッケージ名を付ける必要があります。多数のパッケージを配置する場合、パッケージ名に含まれるそれぞれの識別子を使って、パッケージを論理的にグループ化できます。たとえば数学関数のライブラリを開発する場合、数学関数の各カテゴリーに対応する次のようなパッケージを作成できます。
Curl 言語では、パッケージ名は必ずしも一意である必要はありません。たとえば、名前は同じでバージョンが異なる 2 つのパッケージを同時にインポートできます。ただし、できるだけ一意の名前を付けるようにしてください。一般的な方法の一つは、所属組織のインターネット ドメイン名を逆の順序でパッケージ名の前に付加することです。たとえば、所属組織が example.com というインターネット ドメイン名を取得している場合、この方法に従ったパッケージ名は次のようになります。
他で使われているパッケージ名を接頭辞とするパッケージ名は正当ですが、使用しないことをお勧めします。以下では、二つの名前でパッケージをインポートする例を挙げてみます。
COM.EXAMPLE.MATH.TRIG を一旦インポートすると、これよりも短い名前である COM.EXAMPLE.MATH を隠すことになります。そのため、 例えば、OpenPackage の引数として COM.EXAMPLE.MATH を参照しようとすると失敗します。
注意: CURL という文字列で始まるパッケージ名は、SCSK 株式会社によってすべて予約されています。パッケージ名の前に CURL という文字列を使った場合、パッケージ利用時に問題が発生するおそれがあります。

メタデータ

package 宣言の中でそのパッケージに関するメタデータを定義できます。このメタデータに定義できる項目としては、作成者、著作権情報、バージョン番号などがあります。メタデータは、package 宣言が記述されたファイルだけに属するのではなく、パッケージ全体に属します。
アプレットの applet 宣言やマニフェストでの manifest のように、他の Curl コンポーネントに対してメタデータを宣言することもできます。 各コンポーネントにおける特別な意味を持つメタデータに関しては、コンポーネントの宣言に関するドキュメンテーションを参照してください。(例 appletpackagescript)
メタデータを指定するには、パッケージ宣言の中にその情報を記述します。メタデータの各項目は、keyvalue のセットで構成されます。たとえば次のメタ情報の代入において、keyauthorvalue"Joe Soap" です。
author="Joe Soap"
メタデータを指定する際、Curl 言語に組み込まれているキーを使うことも、ユーザー独自のキーを指定することもできます。あらかじめ組み込まれている便利キーは次のとおりです。全リストに関しては、ドキュメンテーションの ComponentMetaData クラスのアクセッサのセクションを参照してください。
キー説明
authorファイルの作成者。作成者の名前を含む String を指定します。author="Joe Soap"
copyrightファイルに関する著作権情報。著作権情報を示す String を指定します。copyright="Copyright SCSK Corporation."
manifest アプレットとスクリプトに関して、get-default-manifest からリターンされた 規定のマニフェストのロケーションを指定します。  パーケージに関しては、明示的なロケーションからインポートされて、さらに、 インポートするコンポーネントのマニフェストから見つからなかった場合にのみ、 これは使用されます。manifest = "my-manifest.mcurl"
versionファイルのバージョン。1 つ以上の正の整数で構成される String を指定します。整数が複数個ある場合はピリオドで区切ります。version="1.2.3"
メタデータのキーには任意の Curl 言語識別子を使用できます。ただし、一部のキーは上述のように特別な意味を持っています。x- というプレフィックスで始まるメタデータ名は、Curl 言語の中で予約されていないので、ユーザーが自由に利用できます。Curl® API の将来のバージョンで特別なメタデータ キーが追加される可能性があるので、ユーザー独自のメタデータ タグには必ず x- で始まる名前を使ってください。そうすれば、将来追加されるキーとの重複を回避できます。
数値型、量型、StringDateTimeDataReadOnlyArray-of を含む、限られた型のみがメタデータには許可されています。 ComponentMetaData.supported-value-type? より、全リストを参照することができます。コンポーネント宣言のメタデータは式ではなくリテラル値である必要があります。

{package MY-PACKAGE,
    x = 1 + 2,    || ERROR
    y = 3,        || OK
    z = {my-proc} || ERROR
}

import

パッケージ内の 1 つまたは複数の定義を現在のファイルにロードするには、import 式を使います。import 式はトップレベル コードでのみ使用できます。つまり、import 式をコード ブロックの中で使うことはできません。import 式の構文を次に示します。
構文:{import [access] [explicit-names from] PACKAGE-NAME
    [, using-name = LOCAL-NAME ]
    [, override? = true ]
    [, location = {url "path"} ]
    [, id="ComponentID-string" ]
    [, transitive-id="ComponentID-string" ]
    [, version = version-string ]
    [, name = value ] ...
}
説明:
accessインポートされるコードに対するアクセス属性。有効なアクセス属性は public および package です。既定のアクセス属性は package です。public を指定した場合、ここでインポートされるパッケージは、現在のファイルをインポートするコードで利用できます。public を指定しなかった場合、ここでインポートされる定義は、現在のパッケージでは利用できますが、現在のパッケージをインポートするコードでは利用できません。
explicit-names
*、または、ローカルの名前空間に直接インポートされる識別子のコンマ区切り形式のリスト。* を指定した場合、PACKAGE-NAME 内のすべてのパブリック定義がローカルの名前空間に暗黙的にインポートされます。
この指定を省略した場合、次のようにパッケージ名を使って PACKAGE-NAME 内で定義されている識別子を修飾する必要があります。
PACKAGE-NAME.identifier
ただし、この指定を使って定義をローカルの名前空間に直接インポートする場合は、識別子の名前をパッケージ名で修飾する必要はありません。
identifier
注意:
定義をローカルの名前空間にインポートする際、1 つの識別子に対して複数の定義を設定しないよう注意してください。
識別子名の重複を回避するには、フォームの明示名を指定することにより、識別子に対して別名を作成します。
old-name as new-name
たとえば、AppletGraphic に対する定義をインポートして、その定義の名前を RealAppletGraphic に変更して AppletGraphic の他の定義との重複を回避したい場合、次のように指定できます。
{import AppletGraphic as RealAppletGraphic
    from CURL.ENGINE.BROWSER
}
PACKAGE-NAMEインポートされるパッケージの名前。
LOCAL-NAME
識別子名を修飾する際に PACKAGE-NAME の代わりに使うローカルの別名。
LOCAL-NAME.identifier
これにより、長いパッケージ名の代わりに短い別名を定義したり (例:CURL.XML.SAX.PARSER の代わりに PARSER を定義)、同じ名前の 2 つのパッケージをインポートする際にパッケージ名の重複を回避することができます。
override?
ここでインポートする定義が、以前に (おそらく暗黙的に) インポートされた定義をオーバーライドするかどうかを示します。
既定の設定は override? = false です。ここでインポートする定義を使って同名の既存の定義をオーバーライドしたい場合にのみ、override? = true と指定します。
path
メインのパッケージ ファイルの場所を示す URL。各 location 引数に対して URL は 1 つしか指定できません。ただし、location 引数は複数個指定できます。
location パラメータは、現バージョンでは Curl RTE によって指定必須とされています。(このことは、API 2.0 より前のバージョンには当てはまりません。)つまり、location 引数を指定した場合にエラーが通知されるのは、指定した URL のいずれかからパッケージをロードできない場合、または、パッケージが以前にキャッシュされており、指定 URL のいずれかから元のパッケージがロードされなかった場合です。
idインポートするパッケージに対する要素識別子。この引数はまれにしか使われません。この引数の詳細については、ComponentMetaData.id に関する API 情報を参照してください。
transitive-idパッケージに対する推移識別子。この引数はまれにしか使われません。この引数の詳細については、ComponentMetaData.transitive-id に関する API 情報を参照してください。
version-string
パッケージのバージョン番号。このキーワード引数を使って、インポートしたいパッケージのバージョン番号を指定できます。version-string"n.n...n"または"n.n...n+"という形式の文字列として指定することをお勧めします。
この引数を指定した場合、Curl アプレットはバージョンの左側の桁が version-string と合致するパッケージだけをインポートします。たとえば version-string の値が 1.3 である場合、パッケージのバージョン 1.31.3.11.3.21.3.1.2、... がロードされます。つまりユーザーは、インポートしたいバージョン番号を範囲指定できます。特定のバージョンだけをロードしたい場合は、そのバージョンを正確に指定します。
name = value次のような追加のメタデータを表します。
vendor = "Foobar Corporation"
このようなメタデータは、package 宣言のメタデータ指定と正確に一致している必要があります。
次の式は、架空の場所から COM.CURL.MATH.TRIG というパッケージをインポートするものです。
{import COM.CURL.MATH.TRIG,
        location="http://www.curl.com/math/trig/load.scurl"
}
import 式に対するアクセス属性の既定値は package です。つまり、COM.CURL.MATH.TRIG パッケージのコンテンツは、現在のパッケージをインポートするコードからは利用できません。あるファイルが現在のパッケージをインポートした場合、そのファイルから COM.CURL.MATH.TRIG パッケージ内の定義を呼び出すことはできません。現在のパッケージをインポートするファイルから COM.CURL.MATH.TRIG パッケージ内の定義を呼び出せるようにするには、アクセス属性を public に設定します。
既定では、import 式は識別子を現在の名前空間にインポートしません。その代わり、識別子をパッケージの名前にバインドします。たとえば、COM.CURL.MATH.TRIG パッケージをインポートした場合、識別子は COM.CURL.MATH.TRIG にバインドされます。したがって、インポートされたパッケージ内の定義にアクセスするには、パッケージ名と識別子を指定する必要があります。たとえば COM.CURL.MATH.TRIG パッケージ内の cos 関数を呼び出すには、COM.CURL.MATH.TRIG.cos と指定します。
次の式は、すべての定義をローカルの名前空間にインポートするものです。このケースにおいて定義にアクセスするには、その定義名 (cos) を指定するだけで済みます。たとえば cos 関数を呼び出すには、cos と指定します。
{import * from COM.CURL.MATH.TRIG,
        location="http://www.curl.com/math/trig/load.scurl"
}
次の式は、cos の定義だけをローカルの名前空間にインポートするものです。このケースにおいて cos の定義にアクセスするには、その定義名 (cos) を指定するだけで済みます。ただし、他の定義にアクセスするには、パッケージ名と定義名を指定する必要があります。たとえば sin 関数にアクセスするには、COM.CURL.MATH.TRIG.sin と指定します。
{import cos from COM.CURL.MATH.TRIG,
        location="http://www.curl.com/math/trig/load.scurl"
}
define-alias 式を使って、インポートする識別子に対する別名を作成できます。詳細については、「define-alias 式」を参照してください。

define-alias

define-alias 式を使って、識別子に対する別名を作成できます。(識別子は、インポートする定義に対するものでもローカルの定義に対するものでもかまいません。)define-alias 式の構文を次に示します。
構文:{define-alias [access-attribute] alias-list}
説明:
access-attribute別名(alias)に対するアクセス属性。有効なアクセス属性は public および package です。既定のアクセス属性は package です。public を指定した場合、別名は、現在のパッケージをインポートするコードで利用できます。package を指定した場合、別名は、現在のパッケージをインポートするコードで利用できません。
alias-list
別名代入のコンマ区切り形式のリスト。ぞれぞれの別名代入の形式は次のとおりです。
new-name = old-name
new-name はコード内で使いたい名前、old-name はインポートした定義の名前です。
次に例を示します。
{define-alias sin = COM.CURL.MATH.TRIG.sin}
{define-alias public log = COM.CURL.MATH.SCIENTIFIC.log}

名前空間に関する問題

他のパッケージから定義をインポートする際、同じ名前を持つ複数の定義をインポートできます。その場合、コードが予期しない結果になったり、クラッシュする可能性があります。パッケージを暗黙的にインポートする場合 (つまり * を使ってインポートする場合)、特に注意する必要があります。また、public アクセス属性を使ってインポートする場合にも注意が必要です。public アクセス属性を使ってインポートした定義は、import 式を含むパッケージをインポートするコードから利用できます。名前空間に関する問題を軽減するため、次の手法を使うことを検討してください。

スーパーパッケージ ファイルの作成

スーパーパッケージとは、他の複数のパッケージまたはスーパーパッケージをパブリックにインポートするファイルのことです。スーパーパッケージを使って、互いに関連のあるパッケージをグループ化できます。この結果、これらの関連パッケージを簡単にインポートできるようになります。スーパーパッケージ ファイルの構文を次に示します。
構文:package-expression
import-expressions
説明:
package-expressionスーパーパッケージを宣言する package 式。詳細については、「パッケージ宣言」を参照してください。
import-expressionsパッケージまたはスーパーパッケージをインポートする import 式。詳細については、「import 式」を参照してください。
たとえば以下のコードは、次の 3 つのパッケージをインポートする COM.CURL.MATH という名前のスーパーパッケージを作成します。
このコードは、各パッケージの定義を COM.CURL.MATH.SUPER スーパーパッケージの名前空間にインポートします。
|| File:     math/load.scurl
|| Contents: COM.CURL.MATH.SUPER super package
|| Author:   Joe Soap

{curl 8.0 package}

{package COM.CURL.MATH.SUPER,
         author = "Joe Soap",
         version = "1.0"}

{import public * from COM.CURL.MATH.TRIG,
        location = "http://www.example.com/math/trig/load.scurl"}
{import public * from COM.CURL.MATH.BITWISE,
        location = "http://www.example.com/math/bitwise/load.scurl"}
{import public * from COM.CURL.MATH.SCIENTIFIC,
        location = "http://www.example.com/math/scientific/load.scurl"}