aboutsummaryrefslogtreecommitdiffstats
path: root/object.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-10-28 06:24:12 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-10-28 06:24:12 +0000
commitab0ed404a5b0fa4783b2010232d53f590ae5067d (patch)
tree731069832b17cffaafc9fdcdd394f1976c7ec576 /object.c
parent1d5160b390f2894482f89826d671a779384264dd (diff)
downloadruby-ab0ed404a5b0fa4783b2010232d53f590ae5067d.tar.gz
NameError#receiver of uninitialized constant
* error.c (name_err_mesg_to_str): quote the name if unprintable. * object.c (check_setter_id): use rb_check_id to convert names. * variable.c (uninitialized_constant): use NameError::message to keep the receiver of uninitialized constant. [Feature #10881] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52321 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'object.c')
-rw-r--r--object.c146
1 files changed, 51 insertions, 95 deletions
diff --git a/object.c b/object.c
index 910fb4e5d1..8356967279 100644
--- a/object.c
+++ b/object.c
@@ -1900,29 +1900,21 @@ rb_class_get_superclass(VALUE klass)
return RCLASS(klass)->super;
}
-#define id_for_setter(name, type, message) \
- check_setter_id(name, rb_is_##type##_sym, rb_is_##type##_name, message)
+#define id_for_var(obj, name, part, type) \
+ id_for_setter(obj, name, type, "`%1$s' is not allowed as "#part" "#type" variable name")
+#define id_for_setter(obj, name, type, message) \
+ check_setter_id(obj, &(name), rb_is_##type##_id, rb_is_##type##_name, message, strlen(message))
static ID
-check_setter_id(VALUE name, int (*valid_sym_p)(VALUE), int (*valid_name_p)(VALUE),
- const char *message)
+check_setter_id(VALUE obj, VALUE *pname,
+ int (*valid_id_p)(ID), int (*valid_name_p)(VALUE),
+ const char *message, size_t message_len)
{
- ID id;
- if (SYMBOL_P(name)) {
- if (!valid_sym_p(name)) {
- rb_name_error_str(name, message, QUOTE(rb_sym2str(name)));
- }
- id = SYM2ID(name);
- }
- else {
- VALUE str = rb_check_string_type(name);
- if (NIL_P(str)) {
- rb_raise(rb_eTypeError, "% "PRIsVALUE" is not a symbol or string",
- name);
- }
- if (!valid_name_p(str)) {
- rb_name_error_str(str, message, QUOTE(str));
- }
- id = rb_intern_str(str);
+ ID id = rb_check_id(pname);
+ VALUE name = *pname;
+
+ if (id ? !valid_id_p(id) : !valid_name_p(name)) {
+ rb_name_err_raise_str(rb_fstring_new(message, message_len),
+ obj, name);
}
return id;
}
@@ -1934,17 +1926,20 @@ rb_is_attr_name(VALUE name)
}
static int
-rb_is_attr_sym(VALUE sym)
+rb_is_attr_id(ID id)
{
- return rb_is_local_sym(sym) || rb_is_const_sym(sym);
+ return rb_is_local_id(id) || rb_is_const_id(id);
}
-static const char invalid_attribute_name[] = "invalid attribute name `%"PRIsVALUE"'";
+static const char wrong_constant_name[] = "wrong constant name %1$s";
+static const char invalid_attribute_name[] = "invalid attribute name `%1$s'";
static ID
-id_for_attr(VALUE name)
+id_for_attr(VALUE obj, VALUE name)
{
- return id_for_setter(name, attr, invalid_attribute_name);
+ ID id = id_for_setter(obj, name, attr, invalid_attribute_name);
+ if (!id) id = rb_intern_str(name);
+ return id;
}
/*
@@ -1966,7 +1961,7 @@ rb_mod_attr_reader(int argc, VALUE *argv, VALUE klass)
int i;
for (i=0; i<argc; i++) {
- rb_attr(klass, id_for_attr(argv[i]), TRUE, FALSE, TRUE);
+ rb_attr(klass, id_for_attr(klass, argv[i]), TRUE, FALSE, TRUE);
}
return Qnil;
}
@@ -1976,7 +1971,7 @@ rb_mod_attr(int argc, VALUE *argv, VALUE klass)
{
if (argc == 2 && (argv[1] == Qtrue || argv[1] == Qfalse)) {
rb_warning("optional boolean argument is obsoleted");
- rb_attr(klass, id_for_attr(argv[0]), 1, RTEST(argv[1]), TRUE);
+ rb_attr(klass, id_for_attr(klass, argv[0]), 1, RTEST(argv[1]), TRUE);
return Qnil;
}
return rb_mod_attr_reader(argc, argv, klass);
@@ -1998,7 +1993,7 @@ rb_mod_attr_writer(int argc, VALUE *argv, VALUE klass)
int i;
for (i=0; i<argc; i++) {
- rb_attr(klass, id_for_attr(argv[i]), FALSE, TRUE, TRUE);
+ rb_attr(klass, id_for_attr(klass, argv[i]), FALSE, TRUE, TRUE);
}
return Qnil;
}
@@ -2026,7 +2021,7 @@ rb_mod_attr_accessor(int argc, VALUE *argv, VALUE klass)
int i;
for (i=0; i<argc; i++) {
- rb_attr(klass, id_for_attr(argv[i]), TRUE, TRUE, TRUE);
+ rb_attr(klass, id_for_attr(klass, argv[i]), TRUE, TRUE, TRUE);
}
return Qnil;
}
@@ -2102,7 +2097,7 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod)
if (p >= pend || !*p) {
wrong_name:
- rb_name_error_str(name, "wrong constant name % "PRIsVALUE, name);
+ rb_name_err_raise(wrong_constant_name, mod, name);
}
if (p + 2 < pend && p[0] == ':' && p[1] == ':') {
@@ -2137,8 +2132,8 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod)
part = rb_str_subseq(name, beglen, len);
OBJ_FREEZE(part);
if (!ISUPPER(*pbeg) || !rb_is_const_name(part)) {
- rb_name_error_str(part, "wrong constant name %"PRIsVALUE,
- QUOTE(part));
+ name = part;
+ goto wrong_name;
}
else if (!rb_method_basic_definition_p(CLASS_OF(mod), id_const_missing)) {
part = rb_str_intern(part);
@@ -2146,14 +2141,12 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod)
continue;
}
else {
- rb_name_error_str(part, "uninitialized constant %"PRIsVALUE"% "PRIsVALUE,
- rb_str_subseq(name, 0, beglen),
- part);
+ rb_name_err_raise("uninitialized constant %2$s::%1$s", mod, part);
}
}
if (!rb_is_const_id(id)) {
- rb_name_error(id, "wrong constant name %"PRIsVALUE,
- QUOTE_ID(id));
+ name = ID2SYM(id);
+ goto wrong_name;
}
mod = RTEST(recur) ? rb_const_get(mod, id) : rb_const_get_at(mod, id);
}
@@ -2183,7 +2176,8 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod)
static VALUE
rb_mod_const_set(VALUE mod, VALUE name, VALUE value)
{
- ID id = id_for_setter(name, const, "wrong constant name %"PRIsVALUE);
+ ID id = id_for_setter(mod, name, const, wrong_constant_name);
+ if (!id) id = rb_intern_str(name);
rb_const_set(mod, id, value);
return value;
}
@@ -2260,7 +2254,7 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
if (p >= pend || !*p) {
wrong_name:
- rb_name_error_str(name, "wrong constant name % "PRIsVALUE, name);
+ rb_name_err_raise(wrong_constant_name, mod, name);
}
if (p + 2 < pend && p[0] == ':' && p[1] == ':') {
@@ -2290,16 +2284,16 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
part = rb_str_subseq(name, beglen, len);
OBJ_FREEZE(part);
if (!ISUPPER(*pbeg) || !rb_is_const_name(part)) {
- rb_name_error_str(part, "wrong constant name %"PRIsVALUE,
- QUOTE(part));
+ name = part;
+ goto wrong_name;
}
else {
return Qfalse;
}
}
if (!rb_is_const_id(id)) {
- rb_name_error(id, "wrong constant name %"PRIsVALUE,
- QUOTE_ID(id));
+ name = ID2SYM(id);
+ goto wrong_name;
}
if (RTEST(recur)) {
if (!rb_const_defined(mod, id))
@@ -2347,20 +2341,10 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
static VALUE
rb_obj_ivar_get(VALUE obj, VALUE iv)
{
- ID id = rb_check_id(&iv);
+ ID id = id_for_var(obj, iv, an, instance);
if (!id) {
- if (rb_is_instance_name(iv)) {
- return Qnil;
- }
- else {
- rb_name_error_str(iv, "`%"PRIsVALUE"' is not allowed as an instance variable name",
- QUOTE(iv));
- }
- }
- if (!rb_is_instance_id(id)) {
- rb_name_error(id, "`%"PRIsVALUE"' is not allowed as an instance variable name",
- QUOTE_ID(id));
+ return Qnil;
}
return rb_ivar_get(obj, id);
}
@@ -2391,7 +2375,8 @@ rb_obj_ivar_get(VALUE obj, VALUE iv)
static VALUE
rb_obj_ivar_set(VALUE obj, VALUE iv, VALUE val)
{
- ID id = id_for_setter(iv, instance, "`%"PRIsVALUE"' is not allowed as an instance variable name");
+ ID id = id_for_var(obj, iv, an, instance);
+ if (!id) id = rb_intern_str(iv);
return rb_ivar_set(obj, id, val);
}
@@ -2418,20 +2403,10 @@ rb_obj_ivar_set(VALUE obj, VALUE iv, VALUE val)
static VALUE
rb_obj_ivar_defined(VALUE obj, VALUE iv)
{
- ID id = rb_check_id(&iv);
+ ID id = id_for_var(obj, iv, an, instance);
if (!id) {
- if (rb_is_instance_name(iv)) {
- return Qfalse;
- }
- else {
- rb_name_error_str(iv, "`%"PRIsVALUE"' is not allowed as an instance variable name",
- QUOTE(iv));
- }
- }
- if (!rb_is_instance_id(id)) {
- rb_name_error(id, "`%"PRIsVALUE"' is not allowed as an instance variable name",
- QUOTE_ID(id));
+ return Qfalse;
}
return rb_ivar_defined(obj, id);
}
@@ -2455,21 +2430,11 @@ rb_obj_ivar_defined(VALUE obj, VALUE iv)
static VALUE
rb_mod_cvar_get(VALUE obj, VALUE iv)
{
- ID id = rb_check_id(&iv);
+ ID id = id_for_var(obj, iv, a, class);
if (!id) {
- if (rb_is_class_name(iv)) {
- rb_name_error_str(iv, "uninitialized class variable %"PRIsVALUE" in %"PRIsVALUE"",
- iv, rb_class_name(obj));
- }
- else {
- rb_name_error_str(iv, "`%"PRIsVALUE"' is not allowed as a class variable name",
- QUOTE(iv));
- }
- }
- if (!rb_is_class_id(id)) {
- rb_name_error(id, "`%"PRIsVALUE"' is not allowed as a class variable name",
- QUOTE_ID(id));
+ rb_name_err_raise("uninitialized class variable %1$s in %2$s",
+ obj, iv);
}
return rb_cvar_get(obj, id);
}
@@ -2497,7 +2462,8 @@ rb_mod_cvar_get(VALUE obj, VALUE iv)
static VALUE
rb_mod_cvar_set(VALUE obj, VALUE iv, VALUE val)
{
- ID id = id_for_setter(iv, class, "`%"PRIsVALUE"' is not allowed as a class variable name");
+ ID id = id_for_var(obj, iv, a, class);
+ if (!id) id = rb_intern_str(iv);
rb_cvar_set(obj, id, val);
return val;
}
@@ -2521,20 +2487,10 @@ rb_mod_cvar_set(VALUE obj, VALUE iv, VALUE val)
static VALUE
rb_mod_cvar_defined(VALUE obj, VALUE iv)
{
- ID id = rb_check_id(&iv);
+ ID id = id_for_var(obj, iv, a, class);
if (!id) {
- if (rb_is_class_name(iv)) {
- return Qfalse;
- }
- else {
- rb_name_error_str(iv, "`%"PRIsVALUE"' is not allowed as a class variable name",
- QUOTE(iv));
- }
- }
- if (!rb_is_class_id(id)) {
- rb_name_error(id, "`%"PRIsVALUE"' is not allowed as a class variable name",
- QUOTE_ID(id));
+ return Qfalse;
}
return rb_cvar_defined(obj, id);
}