構造体でローカル関数を定義することができます。ローカル関数には、関連する関数のセットをパッケージにする便利な機能があり、複数のスクリプトでグローバル関数が定義されるとき、名前の競合を避けることができます。
例:
struct foo ( a, b, c, fn baz n = sqrt (n + 1), fn bar x y = print (x ^ 2 + y ^ 2) )
この構造体定義
foo
は、3 つの要素a
、b
、およびc
と、2 つのローカル関数bar
およびbaz
を定義しています。これらの関数には、次のように構造体内のプロパティとして、または構造体インスタンスのプロパティとしてアクセスすることができます。p = foo.baz q -- access as property of the structure definition value foo.bar x y f = foo 2 3 4 f.bar x y -- access as property of the structure instance
構造体の定義で宣言されているローカル関数は、その構造体で定義されているメンバ データ変数の参照を作成することができます。構造体インスタンスでそのメンバ関数が呼び出されると、参照はそのインスタンスのメンバにアクセスします。これにより、構造体自身で構造体関数のデータ構造を初期化し、維持することができます。構造体のメンバを使用する関数を含むスクリプトの例を次に示します。
スクリプト:
struct RandVals ( RndVals=#(), ptr, eedVal, fn generateRV num fromVal toVal = ( if seedVal != undefined do seed seedVal RndVals=for i=1 to num collect random fromVal toVal ptr=1 RndVals ), fn deleteRv = ( RndVals=#() ptr=undefined undefined ), fn getNextRV = ( if Nvals == 0 do return undefined val=RndVals[ptr] ptr += 1 if ptr >RndVals.count do ptr=1 val ), fn sortRV =(sort RndVals), fn setSeed val = (SeedVal = val), fn setPointer val = ( if val > 0 and val <= RndVals.count then (ptr=val;true) else false ) ) MyRandomVals= RandVals() MyRandomVals.setSeed 12345 MyRandomVals.generateRV 10 0 100 MyRandomVals.getNextRV() MyRandomVals.sortRV() MyRandomVals.setPointer 1 MyRandomVals.getNextRV() MyRandomVals.deleteRv()
出力:
#Struct:RandVals( -- result of struct def lines 1 to 29 RndVals:<data>; Public, sortRV:<fn>; Public, ptr:<data>; Public, seedVal:<data>; Public, generateRV:<fn>; Public, deleteRv:<fn>; Public, getNextRV:<fn>; Public, setSeed:<fn>; Public, setPointer:<fn>; Public) (RandVals RndVals:#() ptr:undefined seedVal:undefined) -- result line 30 12345 -- result line 31 #(23, 59, 79, 68, 17, 72, 84, 16, 89, 72) -- result line 32 23 -- result line 33 #(16, 17, 23, 59, 68, 72, 72, 79, 84, 89) -- result line 34 true -- result line 35 16 -- result line 36 undefined -- result line 37
このスクリプトでは、構造体はデータ メンバ 3 つと関数メンバ 6 つを持ちます。generateRV()
関数での構造体データ メンバに対する参照に注意してください。30 行目では、RndVals
構造体インスタンスが作成され、変数 MyRandomVals
に保存されます。31 行目では、構造体インスタンスの setSeed()
関数が呼び出されます。これで構造体インスタンスのデータ メンバ seedVal
に指定値を保存し、構造体インスタンスのランダム シード変数を初期化します。32 行目では、構造体インスタンスの generateRV()
関数が呼び出されます。これにより、setSeed()
で指定されるシード値を使ってランダム数を初期化し、データ メンバ RndVals
にランダム数の配列を設定および保存し、データ メンバ ptr
を更新し、ランダム数の配列を返します。
構造体で定義されたローカル関数は、すべての構造体インスタンスに保存されません。ローカル関数は構造体の定義でいったん保存され、インスタンスでの引用は構造体内の定義を参照することになります。