概要 - ローカル変数とグローバル変数(AutoLISP)

変数は、その定義方法に基づいた範囲内でローカルまたはグローバルにすることができます。

ローカル変数を使用すると、関数内の変数が他のユーザ定義関数とカスタム アプリケーションの影響を受けないようにすることができます。これらの変数は、その関数呼び出しが処理を完了した後も使用可能なままにはなりません。

関数またはコマンドを定義するときは、ローカル変数のままとする変数は、引数およびローカル変数のリストにおいてスラッシュ( / )の後に追加する必要があります。たとえば次の例は、定数文字列を他の文字列値と組み合わせる ARGTEST という名前の関数を定義します。arg1arg2 の値は、ARGTEST 関数を使用するときに指定した引数によって指定されますが、ccc はこの関数のローカル変数として定義されます。

(defun ARGTEST ( arg1 arg2 / ccc )
  (setq ccc "Constant string")
  (strcat ccc ", " arg1 ", " arg2)
)
ARGTEST

(ARGTEST "String 1" "String 2")
"Constant string, String 1, String 2"

関数の処理が完了すると、ccc の値は失われます。これは、AutoCAD のコマンド プロンプトに対して次のように入力することでテストできます。

!ccc
nil
ヒント: 関数のデバッグがほぼ完了するまでは、変数をローカルにしないでください。変数をすぐにローカルとして宣言しないことで、関数の処理が終了した後に変数に割り当てられる最後の値を確認することができます。

ローカル変数を使用するもう 1 つの利点は、AutoCAD がこれらの変数によって使用されていたメモリ空間を再使用できることです。これに対し、グローバル変数は AutoCAD のメモリ空間内に蓄積されていきます。

一方、関数がロードされている間、関数またはコマンドを複数回使用する間値を保持したい場合や、多数の関数全体で 1 つの値を使用したい場合など、グローバル変数が便利な場合もあります。ただし、変数のすべてまたは多くをグローバル変数にすると、最終的に変数の値を変更してしまい、他の関数との互換性がなくなるというような結果になる可能性が増大します。これは、予期しない動作が起こる原因となる可能性があり、しかもこの問題の原因を特定するのが非常に難しいことがあります。グローバル変数を宣言するときには、意図的にグローバル変数としていると示すことを習慣とするいいでしょう。これを行う一般的な方法は、たとえば *default-layer* のように、変数名の前後にアスタリスクを追加します。

最初に宣言される変数は、すべてグローバル変数です。次のコードでは、グローバル変数とローカル変数の両方の使用例を示します。

(setq *dr-layer* "Doors")
(defun list-layers ( / cur-layer)
  (setq cur-layer (getvar "clayer"))
  (prompt (strcat "\nCurrent layer: " cur-layer "\nDoor layer: " *dr-layer*))
 (princ)
)
LIST-LAYERS

(list-layers)
Current layer: 0
Door layer: Doors

次の操作を実行して、変数に格納された値をテストすることができます。

!cur-layer
nil

!*dr-layer*
"Doors"

関数では変数をローカルとして宣言することができますが、同じ名前の変数をグローバル変数として宣言することもできます。関数のローカル変数リストに変数名を追加すると、同じ名前のグローバル変数は無視されます。次のコード例で、この動作を示します。

(setq var-scope "Global")
(defun list-scope ( / var-scope)
  (if (/= var-scope nil)
    (prompt (strcat "\nScope: " var-scope))
    (prompt (strcat "\nvar-scope is nil"))
  )

  (setq var-scope "Local")
  (prompt (strcat "\nScope: " var-scope))
 (princ)
)

(list-scope)
var-scope is nil
Scope: Local

!var-scope
"Global"

関数が開始されたとき、変数 var-scope は関数の範囲内で値 nil で宣言されます。このため、変数が nil であるかどうかをチェックした際に、var-scope メッセージは nil であるというメッセージが返されます。var-scope を関数のローカル変数リストに追加しなければ、メッセージ「スコープ: グローバル」が表示され、var-scope の値は「ローカル」に変更されたはずです。

(setq var-scope "Global")
(defun list-scope ( / )
  (if (/= var-scope nil)
    (prompt (strcat "\nScope: " var-scope))
    (prompt (strcat "\nvar-scope is nil"))
  )

  (setq var-scope "Local")
  (prompt (strcat "\nScope: " var-scope))
 (princ)
)

(list-scope)
Scope: Global
Scope: Local

!var-scope
"Local"