この章では、Curl® 言語の関数呼び出しの引数について説明します。具体的には、以下の項目について説明します。
このセクションの内容は、関数と総称されるグローバル プロシージャ、匿名プロシージャ、クラス プロシージャ、メソッド、コンストラクタおよびファクトリーに関するものですが、説明を分かりやすくするために以下の例ではすべてグローバル プロシージャを扱っています。この章で説明する概念はテキスト書式およびテキスト プロシージャにも適用します。ただし、テキスト書式およびテキスト プロシージャの引数には異なる構文があります。
要約: | - 2 つのカテゴリ:リストされた引数と残余引数
- 2 つの形式:位置引数とキーワード引数
|
引数で関数に情報を渡すことができます。引数には次の2つのカテゴリがあります。
- リストされた引数は関数の定義で指定されます。リストされた引数は他のほとんどのプログラミング言語で実装される引数に相当します。
- 残余引数により関数は引数を指定せずに無制限に受けることができます。残余引数は関数定義では個々に名前は付けられません。そのかわり、引数のリストの最後にある 3 つのピリオド (...)が、残余引数を受け取る関数を示します。
これらの引数のカテゴリには次の形式のいずれかまたは両方に渡される引数が含まれます。
- 位置引数
引数リストに位置引数を含む場合は、関数の呼び出しで各位置引数の値を指定する必要があります。関数呼び出しの数、データ型および位置引数の順序は関数定義のそれらと一致させる必要があります。次のコードは my-proc プロシージャを呼び出し、int 位置引数を与えます。
{my-proc 13} - キーワード引数
キーワード引数には既定値があります。ユーザーがキーワード引数の値を指定しない場合は、関数は既定値を使用します。関数呼び出しでキーワード引数を指定するには、値を引数名に代入します。次に示すコードは、my-proc プロシージャを呼び出し、my-arg キーワード引数に対して int 値を指定します。{my-proc my-arg=13}
要約: | - 呼び出し元は各位置引数の値を指定する必要があります。
- 呼び出し元は位置引数に対して正しい順序で値を指定する必要があります。
|
位置引数には次の構文があります。
arg-name[:arg-type]
説明:
- arg-name は引数名です。arg-name を指定する際は、有効な Curl 言語識別子を使用します。関数内から引数値を受け取るには arg-name を使用することができます。
- arg-type は、引数のデータ型です。arg-type を指定する際は、有効なデータ型を使用します。データ型の指定はオプションです。arg-type を指定しない場合は、引数には any データ型を想定します。
位置引数の定義の例は次のとおりです。
|| A procedure that takes one integer positional
|| argument (i)
{define-proc public {my-proc1 i:int}:void
|| Body of procedure
}
|| A procedure that takes one "any" positional
|| argument (a)
{define-proc public {my-proc2 a}:void
|| Body of procedure
}
|| A procedure that takes two positional arguments:
|| a bool (b) and a char (c)
{define-proc public {my-proc3 b:bool, c:char}:void
|| Body of procedure
}
関数呼び出しの数、データ型および位置引数の順序は、関数定義のそれらに一致させる必要があります。位置引数の値を与えるには、関数呼び出しで値を指定します。関数呼び出しで複数の引数を指定する場合は、カンマを使用して引数を区切ります。たとえば、次の例はすべて正規のプロシージャ コールです。
{my-proc1 13}
{my-proc2 13}
{my-proc2 'a'}
{my-proc2 "Hello"}
{my-proc2 true}
{my-proc3 true, 'a'}
要約: | - 呼び出し元は各キーワード引数の値を指定する必要はありません。
- 各キーワード引数定義には既定値が含まれます。
- 呼び出し元は、キーワード引数に対して任意の順序で値を指定することができます。
|
キーワード引数には次の構文があります。
arg-name[:arg-type]=arg-value
説明:
- arg-name は引数名です。arg-name を指定する際は、有効な Curl 言語の識別子を使用します。関数内から引数値にアクセスするには arg-name を使用することができます。
- arg-type は、引数のデータ型です。arg-type を指定する際は、有効なデータ型を使用します。データ型の指定はオプションです。arg-type を指定しない場合は、引数は any データ型を想定します。
- arg-value は、引数の既定値です。arg-value は有効な Curl 言語の任意の式になります。式は、定義される関数の範囲内でコンパイラにより評価されます。arg-value が評価される時に、arg-name は最初に、適切な uninitialized-value-for-type にバインドされます。
キーワード引数の定義の例は次のとおりです。
|| A procedure that takes one integer keyword
|| argument (i)
{define-proc public {my-proc4 i:int=0}:void
|| Body of procedure
}
|| A procedure that takes two keyword arguments:
|| a bool (b) and a char (c)
{define-proc public {my-proc5 b:bool=true, c:char='a'}:void
|| Body of procedure
}
関数の署名にキーワード引数を指定する場合は、関数を呼び出す際に、その引数に対して値を指定する必要はありません。キーワード引数の値を指定しない場合は、関数は既定値を使用します(arg-value)。キーワード引数の値を渡すには、関数呼び出しでその値を引数名に代入します。関数呼び出しで引数名を与えるので、キーワード引数を任意の順序で指定することができます。前述の my-proc5 プロシージャの場合、次の例はそれぞれ有効なプロシージャコールを示します。
{my-proc5}
{my-proc5 b=true}
{my-proc5 c='q'}
{my-proc5 b=true, c='q'}
{my-proc5 c='q', b=true}
キーワード引数が複数回指定される場合は、キーワード引数の最後に指定されるインスタンスが引数の連結に使用されます。他の値はすべて評価され、データ型が検査されてから捨てられます。
次に例を示します。
例:
キーワード引数の使用 |
|
|| A procedure that returns the sum of two numbers.
{define-proc public {add-two-numbers number1:int=12, number2:int=13}:int
{return number1 + number2}}
|| Call the procedure, supplying the arguments.
{add-two-numbers}
{add-two-numbers number1=12}
{add-two-numbers number2=13}
{add-two-numbers number1=12, number2=13}
{add-two-numbers number2=13, number1=12}
{add-two-numbers number2=69, number1=12, number2=13}
| |
例:
初期キーワード バインディング |
|
{let number1:int = 12}
{let number2:int = 13}
|| A procedure that returns the sum of two numbers.
{define-proc public {add-two-numbers
number1:int = number1,
number2:int = number2}:int
{return number1 + number2}}
{add-two-numbers}
| |
要約: | - 関数定義では、位置引数およびキーワード引数を任意の順序で指定することができます。
- 関数呼び出しには、関数定義と同じ順序で位置引数を指定しますが、キーワード引数は任意の順序で指定します。
|
関数を位置引数およびキーワード引数で定義するのに、位置引数およびキーワード引数を任意の順序で指定することができます。たとえば、次のコードでは add-two-numbers プロシージャの署名に 1 つの位置引数 (number1) および 1 つのキーワード引数 (number2) が含まれます。
{define-proc public {add-two-numbers number1:int, number2:int=13}:int
{return number1 + number2}
}
関数を位置引数およびキーワード引数で呼び出す場合、キーワード引数を任意の位置と順序で指定することができます。ただし、関数定義と同じ順序で位置引数を指定する必要があります。位置引数間にキーワード引数を含めることができます。ただし、位置引数の相対順序を相互に保持する必要があります。次の例で、上述のプロシージャを呼び出すことができるさまざまな方法をいくつか示します。
例:
キーワード引数と位置引数の使用 |
|
|| A procedure that returns the sum of two numbers.
{define-proc public {add-two-numbers number1:int, number2:int=13}:int
{return number1 + number2}
}
|| Call the procedure, supplying the arguments.
{add-two-numbers 12, number2=13}
{add-two-numbers number2=13, 12}
{add-two-numbers number2=69, 12, number2=13}
| |
要約: | - 引数はすべて関数定義内に表示されます。
- 引数は位置フォーマットまたはキーワード フォーマットを持つことができます。
|
リストされた引数は関数定義に表示されます。リストされた引数は位置引数またはキーワード引数の形式になります。たとえば、次のプロシージャの定義にはリストされた引数が 2 つあります (arg1 および arg2)。リストされた引数はいずれも位置引数です。
{define-proc {my-proc arg1:int, arg2:int}:bool
{return arg1 == arg2}
}
また、次のプロシージャの定義にはリストされた引数が 2 つあります (arg1 および arg2)。この場合は、リストされた引数のいずれもキーワード引数です。
{define-proc {my-proc arg1:int=13, arg2:int=19}:bool
{return arg1 == arg2}
}
最後に、次のプロシージャの定義にはリストされた引数が 3 つあります (arg1, arg2 および arg3)。この場合は、リストされた引数の内 2 つは位置引数で、残りの 1 つはキーワード引数です。
{define-proc {my-proc arg1:int, arg2:bool, arg3:int=19}:bool
{return (arg1 == arg3) and arg2}
}
,
要約: | - 引数のリストの最後にある3つのピリオド (...) は関数が残余引数を受け取ることを示します。
- 引数は位置フォーマットまたはキーワードフォーマットを持つことができます。
- キーワード引数が複数回指定される場合は、関数は最後に指定された引数を使用します。
- 残余引数にデータ型をオプションで指定することができます。ただし、データ型を指定するとキーワード引数を受け取ることができません。
- 特別な形式の for ループを使用して残余引数のコンテナの引数にアクセスします。
|
残余引数により、関数は名前のない引数を無制限に受け取ることができます。残余引数は関数定義では個々に名前は付けられません。そのかわり、関数定義の引数リストの最後にある 3 つのピリオド (...) は、関数が残余引数を受け取ることを示します。
(...) が、関数定義に表示されると任意の数の残余引数が関数呼び出しの際に指定されます。必要に応じて、引数を一切指定しないこともできます。リストされた引数と同様に、残余引数は位置引数またはキーワード引数の形式になります。
残余引数は実際には残余引数コンテナに格納されます。... がコンテナを示します。残余引数は、すべて遭遇される順番でコンテナに格納されます。次に、コンテナで繰り返し処理をして引数にアクセスすることができます。重複するキーワード引数は残余引数コンテナ内で連結されません 。つまり、キーワード引数が複数回指定されると、残余引数のメカニズムにより、発生したものがすべて格納されるということです。
残余引数のデータ型をオプションで指定することができます。データ型を指定すると、残余引数はキーワード引数を含むことができないので、引数はそれぞれ指定のデータ型を持つ必要があります。たとえば、次のコードは一連の残余引数を定義します。各引数は String データ型を持ちます。
残余引数を指定する場合は、3 つのピリオド (...) を引数リストの最後に含めます。次に例を示します。
|| A procedure that takes rest arguments.
{define-proc public {my-proc6 ...}:void
|| Body of procedure
}
|| A procedure that takes two keyword arguments:
|| a bool (b) and a char (c) and rest arguments.
{define-proc public {my-proc7 b:bool=true, c:char='a', ...}:void
|| Body of procedure
}
残余引数のデータ型を指定することもできます。この指定は非常に有用です。次に例を示します。
|| A procedure that can take any number of int arguments
{define-proc public {my-int-proc ...:int}:void
|| Body of procedure
}
残余引数コンテナ内の引数にアクセスするには、特別な形式の
for ループを使用します。この形式の
for ループ構文は次のとおりです。
{for (val-identifier, key-identifier) [key loop-counter] in ... do
statements
}
説明:
- val-identifier は、残余引数コンテナで処理を繰り返すたびに引数値を保持する変数です。val-identifier のデータ型は、既定では any または残余引数に対して指定されたデータ型になります。
- key-identifier は残余引数コンテナで処理を繰り返すたびに引数のキーワードを保持する変数です。 key-identifier は、 #String データ型を持ちます。現在の要素が位置引数の場合は、key-identifier は null 値です。
- loop-counter は、現在のループ カウンタの現在値を保持する int 値です。
呼び出し元が指定した残余引数にキーワード引数が含まれない場合は、次の構文を使用します。
{for val-identifier [key loop-counter] in ... do
statements
}
実行時に for ループに遭遇すると、残余引数コンテナで引数ごとに statements が繰り返し実行されます。次に例を示します。
例:
残余引数での処理 |
|
|| A procedure that takes rest arguments and returns a StringBuf.
{define-proc {my-proc ...}:StringBuf
|| A variable to hold the return value of the procedure.
let result:StringBuf = {StringBuf}
|| For each value in the rest arguments container, concatenate
|| the value to the string and append a space to the end
|| of the string.
|| Note that this loop will generate a runtime error if the
|| rest arguments container has a keyword argument (or, in
|| fact, any argument that is not a StringInterface, which is
|| the base class for strings in the Curl language).
{for v in ... do
{result.concat v}
{result.append ' '}
}
|| Return the string
{return result}
}
{value
|| Some strings.
let s1:String = "Here"
let s2:String = "comes"
let s3:String = "Curl!"
|| Call the procedure, supplying the strings as rest arguments.
{my-proc s1, s2, s3}
}
| |
他の関数呼び出しでは残余引数コンテナを引数として渡すことができることに留意してください。次に例を示します。
例:
残余引数コンテナを引数として渡す |
|
|| A procedure that takes rest arguments and returns a VBox.
{define-proc {my-vbox ...}:VBox
|| Return a call to VBox with the rest arguments container
|| as the first argument. Because the "background"
|| and "spacing" arguments appear after the rest
|| arguments container, these settings will always take
|| effect (even if the same keyword argument appears
|| in the rest arguments container). You can use this
|| technique to ensure that default settings are applied,
|| even if other values are specified as rest arguments.
{return {VBox ..., background="pink", spacing=5pt}}
}
{value
|| Call the procedure, supplying the following rest arguments:
|| 1) a keyword argument indicating the background color of
|| the VBox
|| 2) a keyword argument indicating the alignment in the VBox
|| 3) a String to place in the VBox
|| 4) a Button to place in the VBox
|| 5) a String to place in the VBox
|| 6) a keyword argument indicating the margin of the VBox
{my-vbox
background="beige",
halign="center",
"Hello World",
{CommandButton label="Click Me!"},
"Goodbye",
margin=5pt
}
}
| |
残余引数は関数定義内に反映されないので、初期の残余引数の内容を明示的に記述する必要があります。これにより、関数を呼び出す引数に正しい残余引数が指定されているかどうかを容易に確認することができます。残余引数を記述する際、次を指定する必要があります。
- データ型と位置引数の順序
- 位置引数が条件またはオプションのいずれか
- キーワード、データ型およびキーワード引数の既定値
残余引数を取る関数を呼び出す場合は、指定する引数を決定する関数の記述をチェックします。Curl 言語の構文により残余引数の指定はオプションになります。
要約: | - 残余引数コンテナを引数として関数呼び出しに渡す場合は、呼び出される関数が残余引数を取ることを確認してください。
- 位置引数および残余引数を取る関数を呼び出す場合は、関数に必要な位置引数の数を指定します。
- 関数呼び出しで引数として渡す、残余引数コンテナ内でのキーワード引数の使用を避けてください。
|
関数呼び出しの引数の処理には、システム リソースがコンパイル時および実行時に必要になります。こうしたリソースの要件は重要でない場合がほとんどです。ただし、プログラム実行中にシステムへの過度の要求を引き起こしかねない残余引数の一定の使用は避ける必要があります。
残余引数コンテナを関数呼び出しの引数として渡す場合は、呼び出される関数が残余引数を取ることを確認します。関数呼び出しの最後の引数は残余引数コンテナで、呼び出す関数の引数リストの最後の引数が残余引数であることも確認します。
位置引数および残余引数を取る関数を呼び出す場合は、関数に必要な位置引数の数も指定します。これによって、新しい残余引数コンテナを作成する必要がなくなります。たとえば、次のコードのように、bar の foo の呼び出しは、baz の foo の呼び出しよりもさらに効率的に処理されます。
|| A procedure that takes one positional argument and
|| rest arguments.
{define-proc {foo x:int, ...}:void
|| Body of procedure.
}
|| Efficient use of rest arguments: the call to "foo"
|| has one positional argument and the rest arguments
|| container.
{define-proc {bar ...}:void
{foo 37, ...}
}
|| Inefficient use of rest arguments: the call to "foo"
|| has a positional argument, another positional
|| argument, and the rest arguments container.
{define-proc {baz ...}:void
{foo 37, 94, ...}
}
関数呼び出しで引数として渡す残余引数コンテナ内でのキーワード引数の使用を避けます。使用するとかなり非効率な処理になります。
要約: | - Curl 言語では、Arguments クラスを使用して関数呼び出しの引数を処理します。
- 残余引数コンテナと同様 Arguments オブジェクトは引数を保持するコンテナです。
|
Curl 言語では、
Arguments クラスを使用して引数コンテナを最初のクラス値として処理します。
Arguments クラスを使用して
Arguments オブジェクトを作成することができます。
Arguments オブジェクトは実際に引数を保持するコンテナです (残余引数コンテナが引数を保持するコンテナと同様)。たとえば、次のコードでは
Arguments オブジェクトを定義し、それをいくつかの位置引数およびキーワード引数で初期化しています。
let args:Arguments = {Arguments background = "beige",
color = "blue",
"Here...",
"comes..."}
Arguments クラスのフィールドおよびメソッドを使用して、コンテナの引数を処理することができます。詳細については、『API リファレンス』の
Arguments の説明を参照してください。
Arguments コンテナの引数を関数呼び出しの引数として渡す場合は、この章の次のセクションで説明する
splice 式を使用することができます。
残余引数コンテナと同様、特別な形式の
for ループ型を使用して
Arguments オブジェクトの引数にアクセスできます。この特別な形式の
for ループ構文は次のとおりです。
{for (val-identifier, key-identifier) [key loop-counter] in arg-object do
statements
}
説明:
- val-identifier は、Arguments オブジェクトで処理を繰り返すたびに引数値を保持する変数です。val-identifier のデータ型は推定されます。
- key-identifier はArguments オブジェクトで反復処理するたびにキーワード引数を保持する変数です。 key-identifier は、 String データ型を持ちます。現在の要素が位置引数の場合は、key-identifier は null 値です。
- loop-counter は、現在のループカウンターの現在値を保持する int 値です。
- arg-object は、Arguments のオブジェクトです。
Arguments オブジェクトにキーワード引数が含まれている場合は、必ず key key-identifier 構文を含めてください。含めないと実行時エラーが発生します。
実行時に for ループに遭遇すると、順次 Arguments オブジェクトの要素を繰り返し、引数ごとに statements が実行されます。
要約: | - splice を使用してコンテナを取り、コンテナの要素を引数のリストとして返します。
- 配列、文字列、キュー、セット、ハッシュテーブル、Arguments オブジェクトおよび残余引数コンテナなどのさまざまなコンテナで splice を使用することができます。
- コンパイラは単に splice 式を引数リストの形式でコンテナの要素に置き換えるので splice 式を引数リストとして処理することができます。
|
Curl 言語には、コンテナを取りその要素を引数リストに挿入する
splice と呼ばれる特別な式があります。この式により、コンテナの要素を関数呼び出しの引数として容易に指定することができます。たとえば、
splice 式を使用して、配列の全要素を関数呼び出しの引数として含めることができます。
splice 式を使用して関数の
Arguments オブジェクトと同様にコンテナの内容を渡すこともできます。
for ループで繰り返し処理されるコンテナで
splice を使用することができます。そのようなコンテナには、配列、文字列、キュー、セット、ハッシュテーブル、
Arguments オブジェクトおよび残余引数コンテナが含まれます。コンパイラは単に
splice 式を引数リストの形式でコンテナの要素に置き換えるので
splice 式を引数リストとして処理することができます。
これは、C、 C++ および Java™ などの他のプログラミング言語にはない非常に強力な機能です。splice 式を含むソース コードをコンパイルすると、コンパイラは splice 式を引数リストの形式でコンテナの要素に置き換えます。ただし、パラメータリストのコンテキストのみに splice 式を使用できることに注意してください。それを汎用的に使用してコンテナの要素にアクセスすることはできません。
splice 式には次の構文があります。
{splice container-name}
container-name はコンテナ名です。配列、文字列、キュー、セット、ハッシュテーブル、
Arguments オブジェクトおよび残余引数コンテナなど、Curl 言語のほとんどのコンテナで
splice を使用することができます。たとえば、
my-array と呼ばれる
Array に対して
splice を呼び出すには次の構文を使用します。
splice 式は関数呼び出しの引数リストのコンテキスト内にのみ表示されます。上記の例は適切なコンテキスト内で次のようなものになります。
{my-proc {splice my-array}}
コンパイラは単に splice 式を引数リストの形式でコンテナの要素に置き換えるので splice 式を引数リストとして処理することができます。つまり、splice 式を引数リストの任意の位置に含めることができます。たとえば、次の splice 式の使用はすべて有効です。
{my-proc {splice my-array}}
{my-proc {splice my-array}, arg-n}
{my-proc arg-1, arg-2, {splice my-array}}
{my-proc arg-1, arg-2, {splice my-array}, arg-n}
関数呼び出しの引数に対する 2 つの共通のコンテナで
splice 式を使用することができます。残余引数コンテナ(
...) と
Arguments オブジェクトこれらの引数コンテナのいずれかで
splice 式を使用すると引数の順序を保持して位置引数およびキーワード引数を返します。ただし、
splice を残余引数コンテナで使用すると冗長になり、残余引数コンテナが同じフォーマットで引数を返します。次の例で、位置引数およびキーワード引数が含まれる
Arguments オブジェクトによる
splice の使用を示します。
例:
Arguments オブジェクトによる splice の使用 |
|
{value
|| Define an Arguments container and initialize it with
|| a number of positional and keyword arguments.
let args:Arguments = {Arguments background = "beige",
color = "blue",
"Here...",
"comes..."}
|| Define a VBox and initialize it with the return value
|| from a call to the spaced-vbox procedure.
|| A "splice" expression includes the arguments from the
|| Arguments object initialized above.
let vb:VBox = {spaced-vbox
"Hello world!",
{splice args},
"Curl!"}
|| Display the VBox
vb
}
| |
特に引数を保持するために設計されていないコンテナで使用すると、splice 式は位置引数として要素を返します。この場合に、コンテナによりキーワード構文がサポートされ、キーワードが含まれます。splice 式が、特に引数を保持するために設計されていないコンテナでキーワードに遭遇すると、キーワードは無視されます。
次の例は、配列による splice の使用を示します。
例:
配列による splice の使用 |
|
{value
|| Define an array of strings and initialize it with
|| three strings.
let some-strings:StringArray =
{new StringArray, "Here...", "comes...", "Curl!"}
|| Define a VBox and initialize it with the return value
|| from a call to the spaced-vbox procedure.
|| A "splice" expression includes the elements of the
|| array initialized above as arguments in the procedure call.
let vb:VBox = {spaced-vbox
"Hello world!",
{splice some-strings}}
|| Display the VBox.
vb
}
| |
splice 式の使用をさらに理解するには、
String の配列内容を連結する問題を考慮します。
StringBuf を作成して文字列の中間内容を保持することができます。次に、配列要素を繰り返し
String をそれぞれ
StringBuf に連結することができます。最後に、
StringBuf を
String に変換することができます。ただし、
splice 式を使用して、単に配列要素を
String の呼び出しの引数として指定することができます。次に例を示します。
例:
文字列による splice の使用 |
|
{value
|| Define an array of strings and initialize it with
|| three strings.
let some-strings:StringArray =
{new StringArray, "Here...", "comes...", "Curl!"}
|| Define a String and initialize it with the return value
|| from a call to splice. The "splice" expression includes
|| the elements of the array defined above.
let output-string:String = {String {splice some-strings}}
|| Display the String.
output-string
}
| |
Copyright © 1998-2019 SCSK Corporation.
All rights reserved.
Curl, the Curl logo, Surge, and the Surge logo are trademarks of SCSK Corporation.
that are registered in the United States. Surge
Lab, the Surge Lab logo, and the Surge Lab Visual Layout Editor (VLE)
logo are trademarks of SCSK Corporation.