Hi,

At Tue, 26 Nov 2002 04:23:56 +0900,
Daniel Carrera wrote:
> I know of one warning that it does *not* give (compared to perl):
> 
> $ ruby -we 'var = "hi"'
> $
> $ perl -we '$var = "hi"'
> Name "main::var" used only once: possible typo at -e line 1.
> $

What about this patch?

$ ./i686-linux/miniruby -we 'var = "hi"'
-e:1: warning: `var' is assigned but not used


Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.355 diff -u -2 -p -r1.355 eval.c --- eval.c 22 Nov 2002 09:32:50 -0000 1.355 +++ eval.c 26 Nov 2002 00:17:18 -0000 @@ -742,4 +742,12 @@ dvar_asgn_curr(id, value) } +void +rb_dvar_asgn(id, value) + ID id; + VALUE value; +{ + dvar_asgn(id, value, 0); +} + VALUE * rb_svar(cnt) Index: parse.y =================================================================== RCS file: /cvs/ruby/src/ruby/parse.y,v retrieving revision 1.229 diff -u -2 -p -r1.229 parse.y --- parse.y 17 Nov 2002 14:01:57 -0000 1.229 +++ parse.y 26 Nov 2002 00:19:57 -0000 @@ -2368,4 +2368,14 @@ int ruby__end__seen; static VALUE ruby_debug_lines; +static struct local_vars { + ID *tbl; + int nofree; + int cnt; + int dlev; + struct RVarmap* dyna_vars; + struct local_vars *prev; + int *used; +} *lvtbl; + static NODE* yycompile(f, line) @@ -4586,6 +4596,15 @@ gettable(id) } else if (is_local_id(id)) { - if (dyna_in_block() && rb_dvar_defined(id)) return NEW_DVAR(id); - if (local_id(id)) return NEW_LVAR(id); + int n; + if (dyna_in_block() && rb_dvar_defined(id)) { + if (ruby_verbose && !ruby_in_eval) rb_dvar_asgn(id, Qnil); + return NEW_DVAR(id); + } + if (n = local_id(id)) { + if (lvtbl->used) { + lvtbl->used[n-2] = 0; + } + return NEW_LVAR(id); + } /* method call without arguments */ #if 0 @@ -4647,5 +4666,5 @@ assignable(id, val) } else{ - rb_dvar_push(id, Qnil); + rb_dvar_push(id, INT2FIX(ruby_sourceline)); return NEW_DASGN_CURR(id, val); } @@ -5212,13 +5231,4 @@ new_super(a) } -static struct local_vars { - ID *tbl; - int nofree; - int cnt; - int dlev; - struct RVarmap* dyna_vars; - struct local_vars *prev; -} *lvtbl; - static void local_push(top) @@ -5234,4 +5244,5 @@ local_push(top) local->dlev = 0; local->dyna_vars = ruby_dyna_vars; + local->used = 0; lvtbl = local; if (!top) { @@ -5247,4 +5258,16 @@ local_pop() struct local_vars *local = lvtbl->prev; + if (lvtbl->used) { + int i, max, line = ruby_sourceline; + for (i = 0, max = lvtbl->cnt - 2; i < max; ++i) { + if (lvtbl->used[i]) { + ruby_sourceline = lvtbl->used[i]; + rb_warn("`%s' is assigned but not used", + rb_id2name(lvtbl->tbl[i+3])); + } + } + ruby_sourceline = line; + free(lvtbl->used); + } if (lvtbl->tbl) { if (!lvtbl->nofree) free(lvtbl->tbl); @@ -5281,4 +5304,8 @@ local_append(id) lvtbl->tbl[lvtbl->cnt+1] = id; + if (ruby_verbose) { + REALLOC_N(lvtbl->used, int, lvtbl->cnt); + lvtbl->used[lvtbl->cnt-2] = ruby_sourceline; + } return lvtbl->cnt++; } @@ -5304,9 +5331,9 @@ local_id(id) int i, max; - if (lvtbl == 0) return Qfalse; + if (lvtbl == 0) return 0; for (i=3, max=lvtbl->cnt+1; i<max; i++) { - if (lvtbl->tbl[i] == id) return Qtrue; + if (lvtbl->tbl[i] == id) return i-1; } - return Qfalse; + return 0; } @@ -5383,4 +5410,16 @@ dyna_pop(vars) struct RVarmap* vars; { + if (ruby_verbose) { + struct RVarmap* v = ruby_dyna_vars; + int line = ruby_sourceline; + while (v && v != vars) { + if (v->id && !NIL_P(v->val)) { + ruby_sourceline = FIX2INT(v->val); + rb_warn("`%s' is assigned but not used", + rb_id2name(v->id)); + } + v = v->next; + } + } lvtbl->dlev--; ruby_dyna_vars = vars;
-- Nobu Nakada