AutoLISPでスクリプトを書く際、最初にぶつかる壁のひとつが「変数のスコープ(有効範囲)」です。特に、ローカル変数とグローバル変数の違いを理解していないと、思わぬバグや予期せぬ動作に悩まされることになります。
🧠 そもそも変数とは?
AutoLISPにおける変数は、データを一時的に保存する「箱」のようなものです。数値、文字列、座標リストなど、さまざまなデータを格納できます。(setq a 10) ; 変数aに10を代入
🌍 グローバル変数とは?
グローバル変数は、プログラムの外からでもアクセス可能な変数です。つまり、関数が終了した後も値が保持され、他の関数からも参照できます。
定義例:
(defun drawline () ; グローバル変数を使用 (setq pnt1 (getpoint "\n始点を指定: ")) (setq pnt2 (getpoint "\n終点を指定: ")) (command "line" pnt1 pnt2 "") )
この場合、pnt1
とpnt2
はグローバル変数となり、関数終了後も値が残ります。
✅ メリット:
- 複数の関数間でデータを共有できる
- 状態保持が必要な処理に便利
❌ デメリット:
- 予期せぬ値の上書きによるバグの原因になりやすい
- 名前の衝突リスクが高まる
🔒 ローカル変数とは?
ローカル変数は、関数の中だけで有効な変数です。関数が終了すると値は破棄され、他の関数からはアクセスできません。
定義例:
(defun drawline (/ pnt1 pnt2) ; ローカル変数を宣言 (setq pnt1 (getpoint "\n始点を指定: ")) (setq pnt2 (getpoint "\n終点を指定: ")) (command "line" pnt1 pnt2 "") )
スラッシュ /
の後に並べた変数がローカルとして扱われます。
✅ メリット:
- 他の関数との干渉を防げる
- 保守性・可読性が高まる
❌ デメリット:
- 関数外で値を使いたい場合には不向き
🧪 実験してみよう!
AutoCADのコマンドラインで以下を試してみてください:(defun c:testglobal () (setq a 100) (princ "\nGlobal a = ") (princ a) ) (defun c:testlocal (/ a) (setq a 200) (princ "\nLocal a = ") (princ a) )
(c:testglobal)
を実行した後に !a
と入力すると、値 100
が表示されます。一方、(c:testlocal)
の後に !a
を入力しても、何も表示されません。これは a
がローカル変数として定義されているためです。
🧭 使い分けの指針
用途
推奨スコープ
一時的な計算・処理
ローカル変数
複数関数で共有する設定値
グローバル変数
ユーザー入力の保持
グローバル変数(ただし注意が必要)
デバッグ・ログ用
ローカル変数(必要に応じてグローバル)
🎯 まとめ
AutoLISPでは、変数のスコープを意識することで、より安全で保守性の高いコードを書くことができます。特に複雑なスクリプトや複数関数を扱う場合、ローカル変数を基本とし、必要に応じてグローバル変数を使うのが鉄則です。
コメント