構造体でのローカル関数の定義

構造体でローカル関数を定義することができます。ローカル関数には、関連する関数のセットをパッケージにする便利な機能があり、複数のスクリプトでグローバル関数が定義されるとき、名前の競合を避けることができます。

例:

    struct foo
    (
    a, b, c,
    fn baz n = sqrt (n + 1),
    fn bar x y = print (x ^ 2 + y ^ 2)
    )

この構造体定義 foo は、3 つの要素 ab、および 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 を更新し、ランダム数の配列を返します。

構造体で定義されたローカル関数は、すべての構造体インスタンスに保存されません。ローカル関数は構造体の定義でいったん保存され、インスタンスでの引用は構造体内の定義を参照することになります。