ブロック式

ブロック式とは、構成コードの基本的なコンストラクタのことです。グループ式を使用して一連の式をグループ化し、グループ化された式を 1 つの式のように順に評価することができます。

<block_expr> の構文は以下のとおりです。

( <expr> { (; | <eol>) <expr> } )

それぞれの <expr> が行区切りかセミコロン ; で分割され、カッコで囲まれた一連の式です。

MAXScript では空のブロック式 () も使用できます。これは、後でパスが埋められる空の式を含むコードを増分して構築するときに便利です。空の式を評価すると、undefined 値が生成されます。

例:

    x = 2
    y = 3
    z = 4
    p = [10,10,10]
    centre = [20,20,20]
    (
    d = centre.x^2 - (p.x^2 + p.y^2)
    newz =if d > 0 then sqrt d else p.z
    print newz
    )
    if x < y then (print x; print y; u += 10; print u)

次のように、行区切りまたはセミコロンを混合して使用することができます。

例:

    (
    print x; print y
    p.x += 10
    print p.x; print p.y
    )

ブロック式は <operand> なので、<operand> を入れることのできる場所ならどこにでもブロック式を挿入することができます。他のほとんどの言語はコードのブロックを入れることのできる場所をわずか数ヶ所に制限していますが、MAXScript はこの点が異なります

さらに、MAXScript ではすべての構成が式なので、ブロック式はブロックの最後の <expr> になるよう定義された値を生成します。これにより、次のようにネストされた一連の式を一部の演算のオペランド計算に使用できるようになります。

例:

    b = box()
    b.pos.z =
    (
    d = x^2 - y^2
    if d > 0 then sqrt d else z
    )

ここでは、ブロック式の結果は if 式の最終結果であり、b.pos.z に代入されます。

カッコで囲まれた項目は any<expr> なので、MAXScript の構文をカッコで囲むことにより構文をオペランドに変えることができます。インデックスで指定されたオペランドが if 式の条件結果となる次のような例を記述することができます。

    (if a > b then c else d)[n + 1]

変数のスコープ」で説明されているように、スクリプト ファイルまたはリスナー内のトップ レベルのカッコによって、新しい変数スコープが作成されます。トップ レベルのブロック式を含むブロック式は、すべて新しい変数スコープを作成しません。これは、その変数が内部のブロック式の中でローカルとして明示的に宣言されている場合も同じです。変数のスコープは、そのスコープ内にあるすべてのブロック式にもあてはまります。スコープ内で変数をローカルとして宣言した場合、新しく宣言されたローカル変数は同じ名前の外側の変数をすべて不可視にします。ローカル変数のスコープ内でのこの変数名への参照は、以後この新しいローカル変数が使われます。ローカル変数のスコープの最後に到達すると、次の外部変数が再び可視になります。以下に例を示します。

スクリプト:

    a=1
    (
    local a=2
    (
    local a=3
    )
    print a
    )
    a

出力:

    1 -- result of line 1
    3 -- output of line 7
    3 -- result of block-expression lines 2 to 8
    1 -- result of line 9

高いスコープ レベルで作成されたブロック式で使われる変数名は、現在のスコープで黙示的にローカルとして宣言されます。これは、スクリプトが正しく設定されていない場合に、予期しない実行結果をもたらします。

次のスクリプトを例に考えてみます。

    (b=bend();addmodifier Objs b) -- create bend modifier and apply to objects
    b.angle=10

このスクリプトを最初に実行すると、次のエラー メッセージが表示されます。

    -- Unknown property: "angle" in undefined

このスクリプトは、再び実行すると正常に動作します。理由は、b という名前の変数が実際には 2 つあり、一方はブロック式に対してローカルでブレンド モディファイヤの値を保持し、もう一方はグローバルで undefined 値を保持するためです。2 回目の実行時には、グローバル変数 b が存在するため、ブロック式は黙示的に新しい変数 b を宣言せず、グローバル変数 b を使用します。

また、スクリプトを作成するときは、特にグローバル変数を使用したい場合を除き、すべての変数をローカルとして宣言することをお勧めします。これは、次のような理由によります。

例:

3ds Max R2.5 で次の式を実行すると、値は Box になります。これは、Box3ds Max オブジェクト クラスであるためです。

3ds Max V 4 以降では、変数 box の最初の使用が代入であることが MAXScript により検出され、暗示宣言ローカル変数 box が作成されます。

3ds Max V 4 以降でのこの式の結果は undefined です。

    (if false do box=10;box)