2024/03/28

変数や関数の宣言とスコープ

以前投稿した ビジネスアプリ開発で大切なこと の記事の中で、コーディングルールについて紹介しました。今回は、変数や関数のスコープという視点からプログラムのわかりやすさについて考えたいと思います。

スコープという側面からは変数や関数、定数で区別ありません。記事内では ”変数” や "関数" などと限定しているかのように記載していますが、読みやすくすること、事例に合わせることが目的です。予めご了承ください。


スコープとは?

変数の有効範囲のことをスコープと言い、スコープの範囲内であれば変数に対してアクセスすることができ、値の出し入れが行えます。また、スコープの範囲内では、同じ変数名を宣言できません。逆にスコープの外側であれば同名の変数が定義でき、別の変数として利用できます。

たとえば、次の2つのプログラムはエラーとなります。

◇ スコープ内で同じ変数を宣言

Sub Sample()
   Dim x As Integer
   Dim x As Integer
      ・・・
End Sub

◇ スコープ外で変数にアクセス

Sub SampleA()
   Dim x As Integer
   Call SampleB()
      ・・・
End Sub

Sub SampleB()
   x = x + 1
End Sub


スコープの種類と宣言方法

スコープはプライベートとパブリックに大別されます。

プライベート モジュール内でのみ利用できる変数
パブリック 他のモジュールからもアクセスできる変数

言葉の意味のままなのですが、パブリックは公開されていて、外部から自由にアクセスできるということですね。


変数の宣言は、一般に Dim を使用しますが、Public や Private というキーワードをつけて明示的にスコープを宣言することができます。

また、明示的に宣言する以外に Option Public と (Options) で指定しておくと、デフォルトで Public となります。Option Public を記述しないとデフォルトが Private となります。Option Private という記述はできないので注意してください。

暗黙の宣言 を禁止する Option Declare を含め (Options) の指定と変数宣言スコープとの関係をまとめると次のようになります。

宣言方法
暗黙 Dim Public Private
Option (なし) Private Private Public Private
Public Private Public Public Private
Declare (不可) Private Public Private
Public
Declare
(不可) Public Public Private


スコープの動作

以下の画像は連載 Notes - Excel 連携 で使用したプログラムです。サンプルとして提示しているだけなので、プログラムの中身(機能)は本題ではありません...

スクリプトライブラリ lsXls で宣言された定数をそのライブラリを使用しているエージェント内で利用(アクセス)しています。

ライブラリ内で Public 宣言している場合にはこのように利用できますが、Private の場合はエラーとなります。

同じエージェントで Private の定数の宣言がありました。この定数のスコープはそのエージェント内だけとなります。

Public や Private の宣言は、スクリプトライブラリやエージェントなどさまざまな場所で行えます。そのため、最初の説明で『モジュール』というあいまいな言葉を使用しています。


なお、上記事例では定数を使用しました。スコープという側面では、変数や関数も同様です。例えば関数の場合には次のようになります。

なお、関数 x9ToA は Private と明示されていませんが、Option Public の指定がないので、Private な関数となります(上表参照)。


スコープの宣言ができる場所

上記のとおり Public や Private による宣言は『モジュール』間のアクセスをコントロールする機能です。記述は各モジュール内の (Declarations) セクションとなります。

ただ、すべての (Declarations) で記述できるわけではありません。例えば、フォームのアクションボタンの中に記述するとエラーとなります。

アクションボタン自身がフォーム内のサブモジュールと言え、そんな奥まったところで Public 宣言されたらおかしいからなのだと思います。


また、関数内の変数宣言にも Public や Private を使用できず、Dim を使用します。関数内で宣言された変数はその関数内だけがスコープとなります。


チーム開発とスコープ

上記でも登場したライブラリ lsXls を事例に、今度はスコープの価値について考えてみましょう。

このライブラリの内部に Private の関数 x9ToA があります。例えば、仕様の変更によりこの関数の修正が必要となったとします。

修正するには、既存プログラムに対する影響を測定する必要がありますよね。

事例のように、この関数が Private なら、この関数にアクセスするのはこのライブラリの中だけということが明確にわかります。よって、調査範囲はこのライブラリ lsXls 内だけで済みます。

もし、Public 宣言されていた(あるいは、Option Public で Public 扱いとなっていた)と仮定すれば、調査範囲は lsXls を利用しているすべてのプログラムとなってしまいます。アプリケーション(nsf)全体が調査範囲になるということですね。

このような背景から、チーム開発を意識したプログラミングではスコープはできる限り絞った方が良いことになります。

開発した本人であれば、その関数の前提としたスコープはわかっているはずです。その時点で適切なスコープを与えていれば、後任者の無用な調査時間を削減でき、チームの生産性は向上します。

『動けばいいのではなく後任者にも配慮する』開発者のビジネスマナーと言ってもいいですね。


0 件のコメント:

コメントを投稿