なかだです。

At Mon, 11 Feb 2002 22:59:48 +0900,
Tanaka Akira <akr / m17n.org> wrote:
> ちなみに、Java では初期化されていない可能性がある変数を参照することを
> 禁止しています。Definite Assignment というやつですが、このようなことに
> 興味を持つなら言語仕様を読んでみるとおもしろいかも知れません。

Rubyでは、selfのメソッドとローカル変数に見掛け上違いがないので
そういうわけにはいきませんが、若干の静的なチェックを考えてみま
した。メソッドとローカル変数を同じ名前にするのは間違いの可能性
が高いのでは、ということです。

$ ./miniruby -wc -e a -e a=a
-e:2: warning: `a' may be uninitialized at line 1
Syntax OK


Index: parse.y =================================================================== RCS file: /cvs/ruby/src/ruby/parse.y,v retrieving revision 1.153 diff -u -2 -p -r1.153 parse.y --- parse.y 2002/02/14 08:47:58 1.153 +++ parse.y 2002/02/15 10:29:44 @@ -4284,4 +4284,13 @@ match_gen(node1, node2) } +static struct local_vars { + ID *tbl; + int nofree; + int cnt; + int dlev; + struct local_vars *prev; + struct st_table *vcall; +} *lvtbl; + static NODE* gettable(id) @@ -4315,4 +4324,8 @@ gettable(id) rb_id2name(id), rb_id2name(id)); #endif + if (ruby_verbose) { + if (!lvtbl->vcall) lvtbl->vcall = st_init_numtable(); + st_insert(lvtbl->vcall, id, (char *)ruby_sourceline); + } return NEW_VCALL(id); } @@ -4358,4 +4371,11 @@ assignable(id, val) } else if (is_local_id(id)) { + if (lvtbl->vcall) { + char *line; + if (st_lookup(lvtbl->vcall, id, &line)) { + rb_warning("`%s' may be uninitialized at line %d", + rb_id2name(id), (int)line); + } + } if (rb_dvar_curr(id)) { return NEW_DASGN_CURR(id, val); @@ -4887,12 +4907,4 @@ new_super(a) } -static struct local_vars { - ID *tbl; - int nofree; - int cnt; - int dlev; - struct local_vars *prev; -} *lvtbl; - static void local_push() @@ -4906,4 +4918,5 @@ local_push() local->tbl = 0; local->dlev = 0; + local->vcall = 0; lvtbl = local; } @@ -4918,4 +4931,5 @@ local_pop() else lvtbl->tbl[0] = lvtbl->cnt; } + if (lvtbl->vcall) st_free_table(lvtbl->vcall); free(lvtbl); lvtbl = local;
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦