diff -ur parrot-from/include/parrot/exceptions.h parrot-to/include/parrot/exceptions.h --- parrot-from/include/parrot/exceptions.h 2005-04-13 17:08:08.000000000 -0700 +++ parrot-to/include/parrot/exceptions.h 2005-04-13 17:09:17.000000000 -0700 @@ -115,6 +115,7 @@ NO_CLASS, LEX_NOT_FOUND, PAD_NOT_FOUND, + ATTRIB_NOT_FOUND, GLOBAL_NOT_FOUND, METH_NOT_FOUND, WRITE_TO_CONSTCLASS, diff -ur parrot-from/src/objects.c parrot-to/src/objects.c --- parrot-from/src/objects.c 2005-04-13 17:08:08.000000000 -0700 +++ parrot-to/src/objects.c 2005-04-13 17:08:48.000000000 -0700 @@ -1,6 +1,6 @@ /* Copyright: 2001-2003 The Perl Foundation. All Rights Reserved. -$Id: objects.c 7826 2005-04-13 23:38:16Z chromatic $ +$Id: objects.c 7785 2005-04-06 11:50:59Z leo $ =head1 NAME @@ -52,7 +52,7 @@ return new_array; } -/* Take the class and completely rebuild the attribute stuff for +/* Take the class and completely rebuild the atttribute stuff for it. Horribly destructive, and definitely not a good thing to do if there are instantiated objects for the class */ static void @@ -173,7 +173,7 @@ Create a vtable that dispatches either to the contained PMC in the first attribute (deleg_pmc) or to an overridden method (delegate), depending -on the existence of the method for this class. +on the existance of the method for this class. =cut @@ -446,7 +446,7 @@ parrot_class_register(Interp* interpreter, STRING *class_name, PMC *new_class, PMC *mro)> -This is the way to register a new Parrot class as an instantiable +This is the way to register a new Parrot class as an instantiatable type. Doing this involves putting it in the class hash, setting its vtable so that the C method initializes objects of the class rather than the class itself, and adding it to the interpreter's base type table so @@ -1192,7 +1192,7 @@ */ -/* Life is ever so much easier if a class keeps its attributes at the +/* Life is ever so much easiser if a class keeps its attributes at the end of the attribute array, since we don't have to insert and reorder attributes. Inserting's no big deal, especially since we're going to break horribly if you insert into a class that's been @@ -1281,8 +1281,12 @@ attrib_array = PMC_data(object); attrib_count = ATTRIB_COUNT(object); if (attrib >= attrib_count || attrib < POD_FIRST_ATTRIB) { + real_exception(interpreter, NULL, ATTRIB_NOT_FOUND, + "Attribute '%d' not found", attrib); + /* internal_exception(OUT_OF_BOUNDS, "No such attribute #%d", (int)attrib); + */ } return get_attrib_num(attrib_array, attrib); } @@ -1294,7 +1298,9 @@ PMC *attr_hash; SLOTTYPE *class_array; HashBucket *b; - char *cattr, *cobj; + STRING *delimit; + STRING *attr_name; + int index, length; if (!PObj_is_object_TEST(object)) internal_exception(INTERNAL_NOT_IMPLEMENTED, @@ -1307,12 +1313,21 @@ (Hash*) PMC_struct_val(attr_hash), attr); if (b) return VTABLE_get_integer(interpreter, (PMC*)b->value); - /* escape the NUL char */ - cobj = string_to_cstring(interpreter, attr); - cattr = cobj + strlen(cobj) + 1; - internal_exception(1, "No such attribute '%s\\0%s'", - cobj, cattr); - string_cstring_free(cattr); + + /* Create a delimiter for splitting up the Class\0attribute syntax. */ + delimit = string_from_cstring(interpreter, "\0", 1); + + /* Calculate the offset and the length of the attribute string. */ + index = string_str_index(interpreter, attr, delimit, 0) + 1; + length = string_length(interpreter, attr) - index; + + /* Extract the attribute name and throw the exception. */ + attr_name = string_from_cstring(interpreter, "", 0); + attr_name = string_substr(interpreter, attr, index, length, attr_name, 0); + + real_exception(interpreter, NULL, ATTRIB_NOT_FOUND, + "Attribute '%Ss' not found", attr_name); + return 0; }