ループ式の構成

このセクションでは、Curl® 言語のループ式について説明します。ループ式は、カッコ内のコードを繰り返し評価します。カッコ内のコードが評価される回数は、ループのタイプおよび制御条件によって決まります。Curl 言語には、次のループ式があります。

while

要約:
  • ブール式が true である間、コード ブロックが繰り返し実行されます。
while 式では、ブール式が true である間、繰り返しコードを実行できます。コードを実行する前に、Curl® 実行環境 (RTE) はブール式を評価します。ブール式が true の場合、カッコ内のコードは実行されます。ブール式が false の場合、コードを実行せずに、while 式の最後に移動します。while 式には、次の構文があります。
構文:{while [tag=tag-name,] condition do
body1
[next body2] ...}
説明:
tag-nameこのループの独自のタグ名です。タグ名はオプションです。コードで continue 式または break 式をタグ名とともに使用する場合は、タグ名を指定します。有効な Curl 言語識別子を指定します。詳細については、continue および break を参照してください。
conditionブール式です。
body11 つ以上の Curl 言語式で構成されています。
next body2任意の next 句。一つまたは複数個指定して、 continue 文のターゲットとして使用します。continueを参照してください。
while 式が検出されると、condition が評価されます。conditiontrue の場合、code が実行され、while 式の先頭に戻ります (処理を繰り返します)。conditionfalseの場合、code は実行されず、while 式の終わりに移動します。
while 式は値を返しません。条件が評価され、カッコ内のコード ブロックのステートメントと式が適切な回数評価されます。
while 式の例を以下に示します。

例: while 式の使用
{value
    || Define and initialize an integer variable: start=1.
    || Define a horizontal box variable called message to store
    || and display a string.
    let start:int=1
    let message:HBox={HBox}

    || While start is less than 10 do the following:
    ||  - Place the value of start in message.
    ||  - Increment start (add 1 to its value).
    {while start < 10 do
        {message.add start}
        set start = start + 1
    }

    || Display the contents of message.
    message
}
ループ式の内部で分岐式を使用すると、プログラム フローを変更できます。詳細については、continue および break を参照してください。

until

要約:
  • ブール式が true になるまで、コード ブロックが繰り返し実行されます。
until 式では、ブール式が true になるまで、繰り返しコードを実行します (つまり、ブール式が false である間、繰り返しコードを実行します)。コードの各繰り返し処理の前に、ブール式が評価されます。ブール式が false の場合、カッコ内のコードは実行されます。ブール式が true の場合、コードは実行されず、until 式の最後に移動します。until 式の構文を次に示します。
構文:{until [tag=tag-name,] condition do
body1
[next body2] ...}
説明:
tag-nameこのループの独自のタグ名です。タグ名はオプションです。コードで continue 式または break 式をタグ名とともに使用する場合は、タグ名を指定します。有効な Curl 言語識別子を指定します。詳細については、continue および break を参照してください。
conditionブール式です。
body1 つ以上の Curl 言語式で構成されています。
next body2任意の next 句。一つまたは複数個指定して、 continue 文のターゲットとして使用します。continue.を参照してください。
until 式が検出されると、condition が評価されます。conditionfalse の場合、code が実行され、until 式の先頭に戻ります (処理を繰り返します)。conditiontrue の場合、code は実行されず、until 式の最後に移動します。
until 式は値を返しません。条件が評価され、カッコ内のコード ブロックのステートメントと式が適切な回数評価されます。
until 式の例を以下に示します。

例: until 式の使用
{value
    || Define and initialize an integer variable: start=1.
    || Define a horizontal box variable called message to store
    || and display a string.
    let start:int=1
    let message:HBox={HBox}

    || Until start is equal to 10 do the following:
    ||  - Place the value of start in message.
    ||  - Increment start (add 1 to its value).
    {until start == 10 do
        {message.add start}
        set start = start + 1
    }

    || Display the contents of message.
    message
}
ループ式の内部で分岐式を使用すると、プログラム フローを変更できます。詳細については、continue および break を参照してください。

for

要約:
  • コード ブロックを指定された回数繰り返します。
  • 範囲ループは、範囲内の値ごとにコードを繰り返します。
  • コンテナ ループは、コンテナ内の値ごとにコードを繰り返します。
for 式では、指定された回数分コードを繰り返すことができます。whileuntil とは違って、コードを実行する回数は、ブール式によって決まるのではありません。反復回数は、ループ変数とそのループの設定値によって決まります。for ループには次の 2 つのカテゴリがあります。
for 式は値を返しません。条件が評価され、カッコ内のコード ブロックのステートメントと式が適切な回数評価されます。しかし、for 式そのものは何も値を返しません。
ループ式の内部で分岐式を使用すると、プログラム フローを変更することができます。詳細については、continue および break を参照してください。

範囲ループ

要約:
  • ループ変数、範囲の開始および範囲の終了を指定します。
  • 任意でステップ量を指定できます。
  • ループの内部からループ変数の値を変更することもできます。
範囲ループでは、数字範囲の値ごとにカッコ内のコードが実行されるので、そのような名称が付けられています。ループ変数、範囲の開始および範囲の終了を指定します。変数は範囲開始値に設定されます。コードが実行されるごとに、ループ変数はループ条件に従ってインクリメントまたはデクリメントされます。ループ変数が範囲終了値に達するまで、コードが繰り返し実行され、各実行後にループ変数がインクリメントまたはデクリメントされます。任意で、毎回変数をインクリメントまたはデクリメントする量を指定できます。これはステップ量と呼ばれます。
Curl 言語では、ループの内部からループ変数の値を変更することもできます。この機能により、for ループの通常の処理フローを回避する for ループを作成できます。しかし、この機能を使用する時は、無限ループにならないように注意する必要があります。
ループの内部からループ変数の値は変更できますが、ループの内部からループの設定値を変更することはできません。ループ設定値には、範囲開始、範囲終了およびステップ量があります。ループ設定値は最初のループの繰り返しが行われる前に 1 度計算されます。ループ設定値は、以降の繰り返しでは計算し直されません。
範囲ループには、以下の 4 つのフォームがあります。
{for ... to ... step ... do ...}
for ループのこのフォームでは、範囲開始から範囲終了の間のループ変数値 (範囲終了時の値も含める) ごとに、コードを実行します。つまり、for 式のこのフォームでは、ループ変数が範囲終了値以下である間、実行されることになります。このフォームの構文を次に示します。
構文:{for [tag=tag-name,] variable-name[:type] = start-range to end-range [step step-value] do
body1
[next body2] ... }
説明:
tag-nameこのループの独自のタグ名です。タグ名はオプションです。codecontinue 式または break 式をタグ名とともに使用する場合は、タグ名を指定します。有効な Curl 言語識別子を指定します。詳細については、continue および break を参照してください。
variable-nameループ変数の名前です。一意の識別子を指定します。
typeループ変数のデータ型です。ループ変数のデータ型の指定はオプションです。型を指定しない場合は、start-range の型が推定され、ループ変数のデータ型として使用されます。
start-range範囲の開始 (ループ変数の初期値) です。
end-range範囲の終了 (ループ変数の終了値) です。
step-value各実行後にループ変数がインクリメントされる量です。データ型の指定はオプションです。ステップ量を指定しない場合は、ループ変数は毎回 1 ずつ (float値の場合は 1.0 ずつ) インクリメントされます。必ず正の数を指定してください。ゼロ (0) を指定した場合、ループを終了させる別の手段を提供しなければコードは無限ループに入ります。
body11 つ以上のCurl 言語式で構成されています。
next body2任意の next 句。一つまたは複数個指定して、 continue 文のターゲットとして使用します。continue を参照してください。
このような for 式が検出されると、ループ変数が定義され、start-range に初期化されます。ループ変数が end-range 以下の場合、code は実行されます。code 実行後、ループ変数がインクリメントされます。ループ変数が end-range 以下の場合、code はもう 1 度実行されます。ループ変数の更新、ループ終了の確認および code の実行というこのプロセスは、ループ変数が end-range より大きくなるまで続行されます。次に例を示します。

例: {for ... to ... step ... do ...} 範囲ループの使用
{value
    || Define a horizontal box variable called message to store
    || and display a string.
    let message:HBox={HBox}

    || Define x to be an integer.  Initialize x to 0.
    || Increment x by 1 after each iteration of the
    || loop (default).  For each value of x up to and
    || including 8, do the following:
    ||  - Place the value of x in message.
    {for x:int=0 to 8 do
        {message.add x}
    }

    || Display the contents of message.
    message
}
step 句を使用する例を次に示します。

例: {for ... to ... step ... do ...} 範囲ループでのステップ句の使用
{value
    || Define a horizontal box variable called message to store
    || and display a string.
    let message:HBox={HBox}

    || Define x to be an integer.  Initialize x to 0.
    || Increment x by 2 after each iteration of the
    || loop.  For each value of x up to and including
    || 8, do the following:
    ||  - Place the value of x in message.
    {for x:int=0 to 8 step 2 do
        {message.add x}
    }

    || Display the contents of message.
    message
}
ループの内部からループ変数値を変更する例を以下に示します。このケースでは、ループ変数は次の繰り返しが 3 で割り切れる場合にインクリメントされます。ループ変数値は、ループの各繰り返し処理の終わりでもインクリメントされます。そのため、ループ変数値を手動でインクリメントする繰り返し処理では、ループ変数は実際には 2 回インクリメントされることになります(このようにして、3 で割り切れる繰り返し処理を回避します)。

例: ループ変数値の変更
{value
    || Define a horizontal box variable called message to store
    || and display a string.
    let message:HBox={HBox}

    || Define x to be an integer.  Initialize x to 0.
    || For each value of x up to and including 8, do the
    || following:
    ||  - Place the value of x in message.
    ||  - If the next iteration of x (that is x + 1)
    ||    will be divisible by 3, then increment x
    ||    to avoid executing the loop for values of x
    ||    that are divisible by 3 (remember that x
    ||    is also incremented at the end of each
    ||    iteration.)
    {for x:int=0 to 8 do
        {message.add x}
        {if (x + 1) mod 3 == 0 then
            set x = x + 1
        }
    }

    || Display the contents of message.
    message
}
ステップ量を設定する変数の値を変更する例を以下に示します。ループ設定値は、最初のループ処理が行われる前にのみバインドされます。ループ設定値は、以降の繰り返しではバインドされません。この例のループには、ステップ量を設定する変数をインクリメントする式があります。しかし、ステップ量はループの最初の繰り返し処理が行われる前にバインドされたため、ループの各繰り返し処理におけるステップ量は変更されません。

例: ステップ量を設定する変数の値の変更
|| Define a horizontal box variable called message to store
|| and display a string.
{let message:HBox={HBox}}

|| Define a to be a variable that holds the step
|| amount.  Initialize a to the value 1.
{let a:int = 1}

|| Define x to be an integer.  Initialize x to 0.
|| For each value of x up to and including 9, do the
|| following:
||  - Place the value of x in message.
||  - Increment the value of a.
{for x:int=0 to 9 step a do
    {message.add x}
    set a = a + 1
}

|| Display the contents of message.
{value message}

|| Display the value of a.
{value a}
{for ... below ... step ... do ...}
for ループのこのフォームは、{for ... to ... step ... do ...} に似ていますが、値が範囲終了値に達したときにはループを実行ません。つまり、for 式のこのフォームでは、ループ変数が範囲終了値より小さい間実行されることになります。このフォームは、belowto の位置にある以外は、for ... to ... step ... do ... と同じ構文になります。
構文:{for [tag=tag-name,] variable-name[:type] = start-range below end-range [step step-value] do
code}
次に例を示します。

例: {for ... below ... step ... do ...} 範囲ループの使用
{value
    || Define a horizontal box variable called message to store
    || and display a string.
    let message:HBox={HBox}

    || Define x to be an integer.  Initialize x to 0.
    || Increment x by 1 after each iteration of the
    || loop (default).  For each value of x up to 8,
    || do the following:
    ||  - Place the value of x in message.
    {for x:int=0 below 8 do
        {message.add x}
    }

    || Display the contents of message.
    message
}
step 句を使用する例を次に示します。

例: {for ... below ... step ... do ...} 範囲ループでのステップ句の使用
{value
    || Define a horizontal box variable called message to store
    || and display a string.
    let message:HBox={HBox}

    || Define x to be an integer.  Initialize x to 0.
    || Increment x by 2 after each iteration of the
    || loop.  For each value of x up to 8, do the
    || following:
    ||  - Place the value of x in message.
    {for x:int=0 below 8 step 2 do
        {message.add x}
    }

    || Display the contents of message.
    message
}
{for ... downto ... step ... do ...}
for ループのこのフォームは、ループ変数がステップ量でデクリメントされる以外は、{for ... to ... step ... do ...} に似ています。つまり、for 式のこのフォームでは、ループ変数が範囲終了値以上である間、実行されることになります。このフォームは、downtoto の位置にある以外は、for ... to ... step ... do ... と同じ構文になります。
構文:{for [tag=tag-name,] variable-name[:type] = start-range downto end-range [step step-value] do
code}
このような for 式が検出されると、ループ変数が定義され、start-rangeに初期化されます。ループ変数が end-range 以上の場合、code は実行されます。code 実行後、ループ変数がデクリメントされます。ループ変数が end-range 以上の場合、code はもう 1 度実行されます。ループ変数の更新、ループ終了の確認および code の実行というこのプロセスは、ループ変数が end-range より小さくなるまで続行されます。次に例を示します。

例: {for ... downto ... step ... do ...} 範囲ループの使用
{value
    || Define a horizontal box variable called message to store
    || and display a string.
    let message:HBox={HBox}

    || Define x to be an integer.  Initialize x to 8.
    || Decrement x by 1 after each iteration of the
    || loop (default).  For each value of x down to 0,
    || do the following:
    ||  - Place the value of x in message.
    {for x:int=8 downto 0 do
        {message.add x}
    }

    || Display the contents of message.
    message
}
{for ... above ... step ... do ...}
for ループのこのフォームは、ループ変数が範囲終了値より大きい間のみデクリメントされる以外は、{for ... downto ... step ... do ...} に似ています。このフォームは、abovedownto の位置にある以外は、for ... downto ... step ... do ... と同じ構文を持ちます。
構文:{for [tag=tag-name,] variable-name[:type] = start-range above end-range [step step-value] do
code }
次に例を示します。

例: {for ... above ... step ... do ...} 範囲ループの使用
{value
    || Define a horizontal box variable called message to store
    || and display a string.
    let message:HBox={HBox}

    || Define x to be an integer.  Initialize x to 8.
    || Decrement x by 1 after each iteration of the
    || loop (default).  For each value of x down to but
    || not including 0, do the following:
    ||  - Place the value of x in message.
    {for x:int=8 above 0 do
        {message.add x}
    }

    || Display the contents of message.
    message
}
       

コンテナ ループ

要約:
  • コンテナ内の値ごとにコード ブロックを繰り返します。
  • ループ本体は、現在の要素の値にアクセスできます。
  • ループ本体は、現在の要素のインデックスまたはキーにアクセスできます。
  • イテレータは再使用する前にリセットする必要があります。
コンテナ ループでは、指定されたコンテナ オブジェクトの要素ごとにカッコ内のコードが実行されるので、このように指定されます。コンテナ ループは、to-Iterator メソッドを持つオブジェクトを繰り返すのに使用できます。Curl 言語に組み込まれているクラスの多くは、to-Iterator メソッドを持ちます。文字列、配列、セット、ハッシュ テーブル、引数リストおよび残余引数配列に関するメソッドがこれらのクラスに含まれています。したがって、たとえば for ループを使用して、文字列の 1 文字ごとにカッコ内のコードを実行することができます。また、for ループを使用して、配列の要素ごとにカッコ内のコードを実行することもできます。to-Iterator または for-loop-count メソッドを提供して、独自に作成したオブジェクトでコンテナ ループを使用することもできます。詳細については、『API リファレンス』の for を参照してください。残余引数配列での forループの使い方については、「残余引数」セクションを参照してください。
注意: コンテナを繰り返し処理する場合、ループの内部からコンテナの内容を変更しないでください。変更すると、動作や結果が不定になります。
コードの繰り返し処理ごとに、現在の要素情報が 1 つ以上の変数に代入されます。これらの変数に設定された情報は、ループのコード内で使用できます。具体的には、次の情報を変数に代入できます。
for ループ内のイテレータを再使用するには、Iterator-of.reset を使ってイテレータをリセットします。
これらの変数代入に対応する 3 つのコンテナ ループのフォームがあります。
{for ... in ... do ...}
for コンテナ ループのこのフォームでは、該当する要素の値が変数に代入されます。このフォームの構文を次に示します。
構文:{for [tag=tag-name,] element-value[:type] in container do
body1
[next body2] ... }
説明:
tag-nameこのループの独自のタグ名です。タグ名はオプションです。ループで continue 式または break 式をタグ名とともに使用する場合は、タグ名を指定します。有効な Curl 言語識別子を指定します。詳細については、continue および break を参照してください。
element-valueそれぞれの繰り返しでの要素の値が含まれる変数の名前です。一意の識別子を指定します。
type要素の変数のデータ型です。変数のデータ型の指定はオプションです。型を指定しない場合は、データ型は container から推定されます。
containerコンテナ オブジェクトです。有効なコンテナ オブジェクトには、文字列、配列、セットおよびハッシュ テーブルがあります。
body11 つ以上の Curl 言語式で構成されています。
next body2任意の next 句。一つまたは複数個指定して、 continue 文のターゲットとして使用します。continue.を参照してください。
このような for 式が検出されると、container のそれぞれの要素について code が実行されます。code の処理の繰り返しごとに element-value に該当する要素の値が代入されます。次に例を示します。

例: {for ... in ... do ...} コンテナ ループの使用
{value
    || Define a vertical box variable called message to store
    || and display a string.
    let message:VBox={VBox}

    || Define an array a of integers with three values (10,
    || 20, and 30).
    let a:{Array-of int}={{Array-of int} 10, 20, 30}

    || For each value v in the array, place v in
    || message.
    {for v:int in a do
        {message.add v}
    }

    || Display the contents of message.
    message
}
{for key ... in ... do ...}
for コンテナ ループのこのフォームでは、該当する要素のキーが変数に代入されます。このフォームの構文を次に示します。
構文:{for [tag=tag-name,] key key-value[:key-type] in container do
code}
説明:
tag-nameこのループの独自のタグ名です。タグ名はオプションです。コードで continue 式または break 式をタグ名とともに使用する場合は、タグ名を指定します。有効な Curl 言語識別子を指定します。詳細については、continue および break を参照してください。
key-valueそれぞれの繰り返しでの要素のキーが含まれる変数の名前です。一意の識別子を指定します。
key-typeキーが含まれる変数のデータ型です。データ型の指定はオプションです。指定しない場合は、データ型が推定されます。
containerコンテナ オブジェクトです。有効なコンテナ オブジェクトには、文字列、配列、セットおよびハッシュ テーブルがあります。
code1 つ以上の Curl 言語式で構成されています。
このような for 式が検出されると、container のそれぞれの要素について code が実行されます。code の処理の繰り返しごとに key-value に該当する要素のキーが代入されます。次に例を示します。

例: {for key ... in ... do ...} コンテナ ループの使用
{value
    || Define a vertical box variable called message to store
    || and display a string.
    let message:VBox={VBox}

    || Define a as an array of integers with three values (10,
    || 20, and 30).
    let a:{Array-of int}={{Array-of int} 10, 20, 30}

    || For each key k in the array, place k in
    || message.
    {for key k:int in a do
        {message.add k}
    }

    || Display the contents of message.
    message
}
上記の例では、結果として生じる配列にキーの値が含まれています。この例のコードと結果を、前セクションの例 (for ... in ... do ...) と比べてみてください。
{for ... key ... in ... do ...}
for コンテナ ループのこのフォームでは、該当する要素の値が変数に代入され、該当する要素のキーが別の変数に代入されます。このフォームの構文を次に示します。
構文:{for [tag=tag-name,] element-value[:element-type] key key-value[:key-type] in container do
code }
説明:
tag-nameこのループの独自のタグ名です。タグ名はオプションです。コードで continue 式または break 式をタグ名とともに使用する場合は、タグ名を指定します。有効な Curl 識別子を指定します。詳細については、continue および break を参照してください。
element-valueそれぞれの繰り返しでの要素の値が含まれる変数の名前です。一意の識別子を指定します。
element-type要素が含まれる変数のデータ型です。データ型の指定はオプションです。指定しない場合は、データ型は推定されます。
key-valueそれぞれの繰り返しでの要素のキーが含まれる変数の名前です。一意の識別子を指定します。
key-typeキーが含まれる変数のデータ型です。データ型の指定はオプションです。指定しない場合は、データ型は推定されます。
containerコンテナ オブジェクトです。有効なコンテナ オブジェクトには、文字列、配列、セットおよびハッシュ テーブルがあります。
code1 つ以上の Curl 言語式で構成されています。
このような for 式が検出されると、container のそれぞれの要素について code が実行されます。code の処理の繰り返しごとに、該当する要素の値は element-value に代入され、該当する要素のキーは key-value に代入されます。次に例を示します。

例: {for ... key ... in ... do ...} コンテナ ループの使用
{value
    || Define a vertical box variable called message to store
    || and display a string.
    let message:VBox={VBox}

    || Define a as an array of integers with three values (10,
    || 20, and 30).
    let a:{Array-of int}={{Array-of int} 10, 20, 30}

    || For each iteration, place the value v and the key
    || k in message.
    {for v:int key k:int in a do
        {message.add {text {value k} ... {value v}}}
    }

    || Display the contents of message.
    message
}