There is some special handling in the source to suppress the "duplicate argument name" error. The error message only appears in shadowing_lvar_gen
inside parse.y
, the 1.9.3 version looks like this:
static ID
shadowing_lvar_gen(struct parser_params *parser, ID name)
{
if (idUScore == name) return name;
/* ... */
and idUScore
is defined in id.c
like this:
REGISTER_SYMID(idUScore, "_");
You'll see similar special handling in warn_unused_var
:
static void
warn_unused_var(struct parser_params *parser, struct local_vars *local)
{
/* ... */
for (i = 0; i < cnt; ++i) {
if (!v[i] || (u[i] & LVAR_USED)) continue;
if (idUScore == v[i]) continue;
rb_compile_warn(ruby_sourcefile, (int)u[i], "assigned but unused variable - %s", rb_id2name(v[i]));
}
}
You'll notice that the warning is suppressed on the second line of the for
loop.
The only special handling of _
that I could find in the 1.9.3 source is above: the duplicate name error is suppressed and the unused variable warning is suppressed. Other than those two things, _
is just a plain old variable like any other. I don't know of any documentation about the (minor) specialness of _
.
In Ruby 2.0, the idUScore == v[i]
test in warn_unused_var
is replaced with a call to is_private_local_id
:
if (is_private_local_id(v[i])) continue;
rb_warn4S(ruby_sourcefile, (int)u[i], "assigned but unused variable - %s", rb_id2name(v[i]));
and is_private_local_id
suppresses warnings for variables that begin with _
:
if (name == idUScore) return 1;
/* ... */
return RSTRING_PTR(s)[0] == '_';
rather than just _
itself. So 2.0 loosens things up a bit.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…