構造体定義における重複したメンバと関数

3ds Max 2014 より前のバージョンでは、重複したメンバおよび関数定義の両方が許可されています。

3ds Max 2014 より前の例:

    struct test
    (
    test = 1,
    test = 2
    )
    a = test()
    a.test

出力:

    2

3ds Max 2014 から、重複したメンバ定義は許可されず、コンパイル時にエラーが生成されるようになりました。

3ds Max 2014 の例:

    struct test
    (
    test = 1,
    test = 2
    )
    a = test()
    a.test

出力:

    -- Error occurred in anonymous codeblock; filename: ; position: 32; line: 4
    -- Compile error: Duplicate struct member name:  test
    --  In line: test=

メンバと関数の重複した名前にも同じ内容が適用されます。

3ds Max 2014 より前では、重複した名前が原因で、メンバの testundefined になり、関数呼び出し test() がメンバの test へのアクセスを試みることでエラーが発生しました。

3ds Max 2014 より前の例:

    struct test
    (
    test,
    fn test2 = test(),
    fn test = print "hello!"
    )
    a = test()
    a.test2()

出力:

    #Struct:Test(
      Test:<fn>; Public,
      test2:<fn>; Public)
    (Test)
    -- Error occurred in test2(); filename: C:\Program Files\Autodesk\3ds Max 2013\scripts\; position: 40; line: 4
    --  Frame:
    -- Type error: Call needs function or class, got: undefined

3ds Max 2014 からは、メンバの test および関数の test での名前の重複によりコンパイル時にエラーが発生するようになりました。

3ds Max 2014 の例:

    struct test
    (
    test,
    fn test2 = test(),
    fn test = print "hello!"
    )
    a = test()
    a.test2()

出力:

    -- Error occurred in anonymous codeblock; filename: ; position: 52; line: 5
    -- Compile error: Duplicate struct member name:  test
    --  In line: fn test =

重複した関数定義は 3ds Max 2014 以前と以降の両方で許可されています。最後に定義された関数が使用されます。

これにより、関数の前方宣言が実行できるようになっています。

前方宣言を使用しないテスト:

    struct test
    (
    fn test2 = test(),
    fn test = print "hello!"
    )
    a = test()
    a.test2()

出力:

    #Struct:test(
      test2:<fn>; Public,
      test:<fn>; Public)
    (test)
    (test)

前方宣言を使用するテスト:

    struct test
    (
    fn test = (), -- Pre-declare test to allow test2 to "see" it
    fn test2 = test(), -- Point at the pre-declared function
    fn test = print "hello!" -- Replace existing test definition, test2 now sees the new definition
    )
    a = test()
    a.test2()

出力:

    #Struct:test(
      test2:<fn>; Public,
      test:<fn>; Public)
    (test)
    "hello!"
    "hello!"

この場合、関数 test2 はまず最初に出現する test を示し、次に test が再定義されると、test2 は後ろにある test の定義を示すようになります。