関数

関数はプログラミングの基本的な構成要素であり、タスクを実行するステートメントをグループ化するための便利で強力な方法です。これらは、Citrix ADCアプライアンスと拡張コードの間のインターフェイスです。ポリシーの場合は、ポリシー拡張関数を定義します。プロトコルの場合は、プロトコルの動作のコールバック関数を実装します。関数は、関数との間で渡される値と関数に対して実行されるステートメントを指定する関数定義と、特定の入力データを持つ関数を実行し、関数から結果を取得する関数呼び出しで構成されます。

プロトコル動作コールバック関数

TCP クライアントの動作は、TCP クライアントデータストリームイベントを処理するコールバック関数 (on_data) で構成されます。TCP ベースのプロトコルに Message Based Load Balancing (MBLB) を実装するには、このコールバック関数のコードを追加して、クライアントからの TCP データストリームを処理し、バイトストリームをプロトコルメッセージに解析します。

ビヘイビア内のコールバック関数は、処理モジュールの状態であるコンテキストで呼び出されます。コンテキストは、処理モジュールのインスタンスです。たとえば、TCP クライアント動作コールバックは、クライアント TCP 接続ごとに異なるコンテキストで呼び出されます。

コンテキストに加えて、ビヘイビアコールバックは他の引数を持つことができます。通常、残りの引数はペイロードとして渡されます。ペイロードは、すべての引数のコレクションです。したがって、プログラマブル処理モジュールのインスタンスは、インスタンス状態とイベントコールバック関数、つまりコンテキストと動作の組み合わせとして見ることができます。トラフィックはイベントペイロードとしてパイプラインを通過します。

TCPクライアントコールバック関数のプロトタイプ:

            Function                client on_data (ctxt, payload)

                                            //.code

            end

各項目の意味は次のとおりです。

  • ctxt -TCPクライアント処理コンテキスト
  • payload :イベントペイロード
    • payload.d ata-受信したTCPデータ。バイトストリームとして利用できます。

ポリシー拡張関数

NetScalerポリシー表現言語は厳密に型付けされているため、拡張関数の定義では、入力の種類と戻り値を指定する必要があります。Lua 関数定義は、次の型を含むように拡張されました。

function self-type:function-name(parameter1: parameter1-type, etc.): return-type
     statements
end

where,

the types are NSTEXT, NSNUM, NSBOOL, or NSDOUBLE.
<!--NeedCopy-->

self型は、関数に渡される暗黙のselfパラメータの型です。Citrix ADCポリシー式で拡張関数を使用する場合、これは関数の左側にある式によって生成された値です。これを表示するもう 1 つの方法は、この関数によってCitrix ADCポリシー言語でそのタイプが拡張されることです。

パラメータ型は、ポリシー式で拡張関数呼び出しで指定された各パラメータの型です。拡張関数は、0 個以上のパラメータを持つことができます。

return-type は、拡張関数呼び出しによって返される値の型です。ポリシー式の部分(ある場合)への入力であり、関数の右側に入力されます。それ以外の場合は、式の結果の値です。

例:

function NSTEXT:COMBINE_HEADERS() : NSTEXT

ポリシー表現での拡張関数の使用:

HTTP.REQ.FULL_HEADER.AFTER_STR("HTTP/1.1rn").COMBINE_HEADERS()

ここで自己パラメータは、テキスト値であるHTTP.REQ.FULL_HEADER.AFTER_STR(「HTTP/1.1rn」)の結果です。COMBINE_HEADERS () 呼び出しの結果はテキストであり、この呼び出しの右側には何もないため、式全体の結果はテキストになります。

ローカル関数定義

拡張関数のほかに、拡張ファイルにグローバル関数を定義することはできません。しかし、ローカル関数は、通常のLuaの関数文を使用して拡張関数内で定義することができます。これは、関数の名前とそのパラメータの名前(引数とも呼ばれます)を宣言し、Luaのすべての宣言と同様に、任意の型を指定しません。この構文は次のとおりです。

local function function-name(parameter1-name, parameter2-name, etc.)
     statements
end
<!--NeedCopy-->

関数名とパラメータ名はすべて識別子です。(関数名は実際には変数であり、関数文はローカル関数名=関数(パラメータ1など)の略語ですが、関数を使用するためにこの微妙さを理解する必要はありません)。

等は、通常の… の代わりにパラメータ名のパターンを継続するためにここで使用されることに注意してください。これは… それ自体が実際には変数パラメータリストを意味するためです。これはここでは説明しません。

関数本体と戻り値

関数とend文の間の文のブロックは、関数本体です。関数本体では、関数パラメータはローカル変数のように動作し、前述のように、関数呼び出しによって指定された値を持ちます。

return文は、関数の呼び出し元に返される値を提供します。それはブロックの最後に現れなければなりません(関数内で、もしそうなら、forループなど; それはそれ自身のブロックにあることができます戻り値… 終了)。これは、なし、1、または複数の戻り値を指定することができます。

return -- returns nil
return expression -- one return value
return expression1, expression2, ... -- multiple return values
<!--NeedCopy-->

例:

local function fsum(a)
     local sum = 0
     for i = 1, #a do
          sum = sum + a[i]
     end
     return sum
end

local function fsum_and_average(a)
     local sum = 0
     for i = 1, #a do
          sum = sum + a[i]
     end
     return sum, sum/#a
end
<!--NeedCopy-->

関数呼び出し

関数呼び出しは、関数の本体を実行し、そのパラメータの値を指定し、結果を受け取ります。関数呼び出しの構文は、関数名(式 1、式 2 など)で、関数パラメータは対応する式に設定されます。式とパラメータの数は同じである必要はありません。式の数がパラメータよりも少ない場合、残りのパラメータはnilに設定されます。したがって、呼び出しの最後に1つ以上のパラメータをオプションにすることができ、関数がnilでないかどうかをチェックすることによって指定されているかどうかを確認できます。これを行う一般的な方法は、または操作です。

function f(p1, p2) -- p2 is optional
     p2 = p2 or 0 -- if p2 is nil, set to a default of 0
     . . .
end
<!--NeedCopy-->

パラメータよりも多くのエクスプレッションがある場合、残りのエクスプレッション値は無視されます。

前述のように、関数は複数の値を返すことができます。これらのリターンは、複数の代入ステートメントで使用できます。例:

local my_array = {1, 2, 3, 4}
local my_sum, my_ave = sum_and_average(my_array)
<!--NeedCopy-->

反復子関数と汎用forループ

関数を導入したので、一般的なforループについて話すことができます。一般的なforループ(1つの変数を持つ)の構文は次のとおりです。

for variable in iterator(parameter1, parameter2, etc.) do
     statements in the for loop body
end
<!--NeedCopy-->

ここで、iterator()は、ループ本体の各反復で変数の値を提供するゼロ以上のパラメータを持つ関数です。イテレータ関数は、クロージャと呼ばれるテクニックを使用して、イテレーションのどこにあるかを追跡します。これはここで心配する必要はありません。これは、nilを返すことによって、反復の終了を知らせます。イテレータ関数は、複数の代入で使用するために、複数の値を返すことができます。

イテレータ関数の記述は、本書の範囲を超えていますが、概念を説明する便利な組み込みイテレータがいくつかあります。1つは、テーブル内のエントリを反復処理し、2つの値、キーと次のエントリの値を返すペア()イテレータです。

例:

local t = {k1 = "v1", k2 = "v2", k3 = "v3"}
local a = {} -- array to accumulate key-value pairs
local n = 0 -- number of key-value pairs
for key, value in pairs(t) do
     n = n + 1
     a[n] = key .. " = " .. value -- add key-value pair to the array
end
local s = table.concat(a, "; ") -- concatenate all key-value pairs into one string
<!--NeedCopy-->

もう1つの便利なイテレータは、次のCOMBINE_HEADERS()の例で使用されるstring.gmatch()関数です。

関数