2008/05/03

変数のスコープと有効期限

故あってAccessのVBAの講習会へ参加したことのある同僚から、講習会本を借りて、このテの教材はどんなものかなーとちょっと読んでいたわけですが、講習会って、スゴイんですね。「VBAだしなー」と甘く見ていたら、言語の基礎を思った以上にかなりがっつり網羅している。…今思うと、VBA/VB6.0をいじっていた当時、単に私がなにがなんだかわかっていなかっただけなのですが(理屈はわからず「お作法」的に覚えたクチ。VB6.0ユーザーには多いのではないでしょうか)、基本という意味では、VBAの基礎本といえどもそれなりに網羅しているんだなぁ、と妙に感心。普段通いなれた安全な道しか使わない方なので、「そーいえば…」というものも出てきて、勉強/復習になります。

そんなこんなでテキストをみながら、「あぁこのネタにはハマったことがあるなぁ…」と思い出したり発見することも多い今日この頃なのですが、そのひとつが正直に告白しますと、変数のスコープと有効期限です。…基本中の基本ですね!!

VBAにはブロック・レベルのスコープはありませんが、VB.NETにはブロック・レベルのスコープがあります。

「スコープ」についてはブロックの外でブロック内で宣言した変数を呼び出そうとしてもエラーになるので、「あぁこれは使えないんだな」ということがハッキリわかるわけですが、「有効期限」はちょっとわかりにくいですよね。…そうでもないですか?

無教養な私の場合、「スコープ=有効期限」のように思いっきり錯覚していたわけですが、スコープと有効期限は別物なんですよね。VB.NETでのブロック・レベルのスコープでいうなら、変数の有効期間は、プロシージャ全体の有効期間です。

…で、その辺いい加減な理解をしていた私が何をやったかというと、お察しの通り、ブロック内で変数宣言した構造体を、自分で初期化せずに、使ってしまったわけです。当然、「宣言したところで初期化されている」という思い込み、プラス、有効期限もブロック内だという勘違いを前提を元にコーディング。その結果、恐ろしいデータができたので、すぐさまスコープと有効期限の違い、自分の勘違いにも気がつき、「とりあえず、なんでも自分の思うタイミングで初期化しておけば間違いない」というとても初歩的な教訓は自ら体験して得たわけなんですが。基礎本をちゃんと読めばそんなことは書いてあるのに、書いてあることがうまくつながらずに読んでいるとこうなるわけですね。

「スコープ/有効期限といえば、そんなこともやったっけなぁ」と我ながらイタイ思い出を振り返りながらテキストを読んでいると、Accessの場合、「標準モジュールに書いたPrivate変数の有効期限は、MDBを閉じるまで」と書いてあるではないですか。ひょええぇ…。これって、VB.NETでも同じことなんでは?

これまでVBA/VB6.0でいうところのクラスモジュール、およびインスタンス生成のクラスではPrivate変数宣言は使っていました。この場合「フォーム/レポートが開いている間は有効」、「インスタンス生成してそのクラスが生きている間は有効」ということで、迷うほどのこともなくわかりやすく特に問題はありませんでした。でも標準モジュールの類では、私は変数/プロシージャーを含めてPublicなものしか使ったことがなかったんでよね。故にあまり考えたことがなかったということもできますが、スコープ/有効期限は大事、と思いながら、標準モジュールの宣言セレクションで宣言したPrivate変数の有効期限をロクに認識していなかったとは、どーゆーことでしょう。

VB.NETでは標準モジュールにあたるModuleもありますし、それと同等の役割を果たすSharedを宣言しまくりのクラスの場合も、この辺の理屈は一緒の筈です。それなのにこれまでこの辺をロクに認識していなかったとは……。VBA/VB6.0時代同様、このテの場面ではPrivateで変数宣言をしようと思ったことがないので、幸いバグったことはありませんが。あああああ、足元で思いっきり躓いた感じでショックです。痛い、あまりにも痛い…。

モジュールみたいな場所でずっと値の生きているPrivate変数というのは、使いづらそうなので、今後も個人的にはあまり使う場面はイメージできないのですが(インスタンス生成のクラスでカプセル化した方が安心…)、言語の仕様はきっちり読んでいないと怖いですねぇ。自分の使ったことのない新ネタは使う前に仕様は確認はする方ですが、基礎がないと仕様を読む際のポイントもわからないですからねぇ。そしてワナにハマって「あの意味はこれだったのか!」と気がつく。…ときどきこうして基礎本を読んで振り返るのは、なんであれ、まだまだ勉強になります。

0 件のコメント: