From 795c29dcda01fa81a3ccebee4433adabe6778d76 Mon Sep 17 00:00:00 2001 From: eregon Date: Tue, 14 Aug 2012 10:20:44 +0000 Subject: Kernel#inspect: improve consistency and do not call #to_s. A class can now benefit from the nice default #inspect even if it defines #to_s. Also, there is no more unexpected change in #inspect result. Internal structures have been adapted so they don't rely on the removed behavior (#inspect calling overridden #to_s). * object.c (rb_obj_inspect): Kernel#inspect: do not call #to_s. * test/ruby/test_object.rb (test_inspect): add tests for Kernel#inspect. * bignum.c, io.c, numeric.c, object.c, proc.c, vm.c (Init_*): alias #inspect to #to_s where it was expected. [ruby-core:43238][Feature #6130] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36699 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- object.c | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) (limited to 'object.c') diff --git a/object.c b/object.c index 1e005e53af..b7e1b58c81 100644 --- a/object.c +++ b/object.c @@ -450,11 +450,8 @@ inspect_obj(VALUE obj, VALUE str, int recur) * obj.inspect -> string * * Returns a string containing a human-readable representation of obj. - * By default, if the obj has instance variables, show the class name - * and instance variable details which is the list of the name and the result - * of inspect method for each instance variable. - * Otherwise uses the to_s method to generate the string. - * If the to_s method is overridden, uses it. + * By default, show the class name and the list of the instance variables and + * their values (by calling #inspect on each of them). * User defined classes should override this method to make better * representation of obj. When overriding this method, it should * return a string whose encoding is compatible with the default external @@ -479,35 +476,21 @@ inspect_obj(VALUE obj, VALUE str, int recur) * "baz" * end * end - * Baz.new.inspect #=> "baz" + * Baz.new.inspect #=> "#" */ static VALUE rb_obj_inspect(VALUE obj) { - if (RB_TYPE_P(obj, T_OBJECT) && rb_obj_basic_to_s_p(obj)) { - int has_ivar = 0; - VALUE *ptr = ROBJECT_IVPTR(obj); - long len = ROBJECT_NUMIV(obj); - long i; - - for (i = 0; i < len; i++) { - if (ptr[i] != Qundef) { - has_ivar = 1; - break; - } - } - - if (has_ivar) { - VALUE str; - const char *c = rb_obj_classname(obj); + if (rb_ivar_count(obj) > 0) { + VALUE str; + const char *c = rb_obj_classname(obj); - str = rb_sprintf("-<%s:%p", c, (void*)obj); - return rb_exec_recursive(inspect_obj, obj, str); - } + str = rb_sprintf("-<%s:%p", c, (void*)obj); + return rb_exec_recursive(inspect_obj, obj, str); + } else { return rb_any_to_s(obj); } - return rb_funcall(obj, rb_intern("to_s"), 0, 0); } static VALUE @@ -2951,6 +2934,7 @@ Init_Object(void) rb_define_method(rb_cModule, ">=", rb_mod_ge, 1); rb_define_method(rb_cModule, "initialize_copy", rb_mod_init_copy, 1); /* in class.c */ rb_define_method(rb_cModule, "to_s", rb_mod_to_s, 0); + rb_define_alias(rb_cModule, "inspect", "to_s"); rb_define_method(rb_cModule, "included_modules", rb_mod_included_modules, 0); /* in class.c */ rb_define_method(rb_cModule, "include?", rb_mod_include_p, 1); /* in class.c */ rb_define_method(rb_cModule, "name", rb_mod_name, 0); /* in variable.c */ @@ -3003,6 +2987,7 @@ Init_Object(void) rb_cTrueClass = rb_define_class("TrueClass", rb_cObject); rb_define_method(rb_cTrueClass, "to_s", true_to_s, 0); + rb_define_alias(rb_cTrueClass, "inspect", "to_s"); rb_define_method(rb_cTrueClass, "&", true_and, 1); rb_define_method(rb_cTrueClass, "|", true_or, 1); rb_define_method(rb_cTrueClass, "^", true_xor, 1); @@ -3015,6 +3000,7 @@ Init_Object(void) rb_cFalseClass = rb_define_class("FalseClass", rb_cObject); rb_define_method(rb_cFalseClass, "to_s", false_to_s, 0); + rb_define_alias(rb_cFalseClass, "inspect", "to_s"); rb_define_method(rb_cFalseClass, "&", false_and, 1); rb_define_method(rb_cFalseClass, "|", false_or, 1); rb_define_method(rb_cFalseClass, "^", false_xor, 1); -- cgit v1.2.3