diff --git a/ChangeLog b/ChangeLog index 4c94d17917..2608d91ca2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +Wed Aug 15 20:47:49 2012 Benoit Daloze + + * object.c (rb_obj_inspect): Kernel#inspect: 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. + + * NEWS: Add note about the change. + + * bignum.c, io.c, numeric.c, object.c, proc.c, vm.c (Init_*): + Adapt internal structures (by aliasing #inspect to #to_s) so they + don't rely on the removed behavior (#inspect calling overridden #to_s). + + * test/ruby/test_object.rb (test_inspect): add tests for Kernel#inspect. + + * lib/pp.rb (class PP): do not call #to_s anymore, as #inspect + no more does (mame). + + * test/test_pp.rb (class PPInspectTest): remove related assertion (mame). + [ruby-core:43238][Feature #6130] + + * test/drb/drbtest.rb (DRbCore#teardown, DRbAry#teardown): + adapt DRb tests with the new change (shirosaki). + [ruby-core:47182][Bug #6866] + Wed Aug 15 18:05:37 2012 NAKAMURA Usaku * lib/test/unit.rb (Test::Unit::Runner#failed): need to delete the diff --git a/NEWS b/NEWS index ce1dc8be9f..5715b552b4 100644 --- a/NEWS +++ b/NEWS @@ -46,6 +46,8 @@ with all sufficient information, see the ChangeLog file. * __callee__ has returned to the original behavior, and now returns the called name but not the original name in an aliased method. + * Kernel#inspect does not call #to_s anymore + (it used to call redefined #to_s). * LoadError * added method: diff --git a/bignum.c b/bignum.c index 3394825ce8..fc713a00cd 100644 --- a/bignum.c +++ b/bignum.c @@ -3835,6 +3835,7 @@ Init_Bignum(void) rb_cBignum = rb_define_class("Bignum", rb_cInteger); rb_define_method(rb_cBignum, "to_s", rb_big_to_s, -1); + rb_define_alias(rb_cBignum, "inspect", "to_s"); rb_define_method(rb_cBignum, "coerce", rb_big_coerce, 1); rb_define_method(rb_cBignum, "-@", rb_big_uminus, 0); rb_define_method(rb_cBignum, "+", rb_big_plus, 1); diff --git a/io.c b/io.c index 52eb49574b..b1a38cc707 100644 --- a/io.c +++ b/io.c @@ -11505,6 +11505,7 @@ Init_IO(void) rb_define_method(rb_cARGF, "initialize", argf_initialize, -2); rb_define_method(rb_cARGF, "initialize_copy", argf_initialize_copy, 1); rb_define_method(rb_cARGF, "to_s", argf_to_s, 0); + rb_define_alias(rb_cARGF, "inspect", "to_s"); rb_define_method(rb_cARGF, "argv", argf_argv, 0); rb_define_method(rb_cARGF, "fileno", argf_fileno, 0); diff --git a/lib/pp.rb b/lib/pp.rb index 94269abe65..6e0c797d2e 100644 --- a/lib/pp.rb +++ b/lib/pp.rb @@ -265,8 +265,7 @@ class PP < PrettyPrint module ObjectMixin # 1. specific pretty_print # 2. specific inspect - # 3. specific to_s - # 4. generic pretty_print + # 3. generic pretty_print # A default pretty printing method for general objects. # It calls #pretty_print_instance_variables to list instance variables. @@ -283,18 +282,10 @@ class PP < PrettyPrint inspect_method = method_method.call(:inspect) rescue NameError end - begin - to_s_method = method_method.call(:to_s) - rescue NameError - end if inspect_method && /\(Kernel\)#/ !~ inspect_method.inspect q.text self.inspect elsif !inspect_method && self.respond_to?(:inspect) q.text self.inspect - elsif to_s_method && /\(Kernel\)#/ !~ to_s_method.inspect - q.text self.to_s - elsif !to_s_method && self.respond_to?(:to_s) - q.text self.to_s else q.pp_object(self) end diff --git a/numeric.c b/numeric.c index 73626e1c05..5ac5449238 100644 --- a/numeric.c +++ b/numeric.c @@ -3660,6 +3660,7 @@ Init_Numeric(void) rb_cFixnum = rb_define_class("Fixnum", rb_cInteger); rb_define_method(rb_cFixnum, "to_s", fix_to_s, -1); + rb_define_alias(rb_cFixnum, "inspect", "to_s"); rb_define_method(rb_cFixnum, "-@", fix_uminus, 0); rb_define_method(rb_cFixnum, "+", fix_plus, 1); @@ -3720,6 +3721,7 @@ Init_Numeric(void) rb_define_const(rb_cFloat, "NAN", DBL2NUM(NAN)); rb_define_method(rb_cFloat, "to_s", flo_to_s, 0); + rb_define_alias(rb_cFloat, "inspect", "to_s"); rb_define_method(rb_cFloat, "coerce", flo_coerce, 1); rb_define_method(rb_cFloat, "-@", flo_uminus, 0); rb_define_method(rb_cFloat, "+", flo_plus, 1); 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; + if (rb_ivar_count(obj) > 0) { + VALUE str; + const char *c = rb_obj_classname(obj); - 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); - - 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); diff --git a/proc.c b/proc.c index 6ccb888bd7..9ed6dbb2e7 100644 --- a/proc.c +++ b/proc.c @@ -2217,6 +2217,7 @@ Init_Proc(void) rb_define_method(rb_cProc, "eql?", proc_eq, 1); rb_define_method(rb_cProc, "hash", proc_hash, 0); rb_define_method(rb_cProc, "to_s", proc_to_s, 0); + rb_define_alias(rb_cProc, "inspect", "to_s"); rb_define_method(rb_cProc, "lambda?", rb_proc_lambda_p, 0); rb_define_method(rb_cProc, "binding", proc_binding, 0); rb_define_method(rb_cProc, "curry", proc_curry, -1); diff --git a/test/drb/drbtest.rb b/test/drb/drbtest.rb index 1cb8b1f95b..d0156fd9e4 100644 --- a/test/drb/drbtest.rb +++ b/test/drb/drbtest.rb @@ -73,7 +73,7 @@ module DRbCore def teardown @ext.stop_service if defined?(@ext) && @ext DRbService.manager.unregist(@service_name) - while (@there.inspect rescue nil) + while (@there.to_s rescue nil) # nop end signal = /mswin|mingw/ =~ RUBY_PLATFORM ? :INT : :TERM @@ -294,7 +294,7 @@ module DRbAry def teardown @ext.stop_service if defined?(@ext) && @ext DRbService.manager.unregist(@service_name) - while (@there.inspect rescue nil) + while (@there.to_s rescue nil) # nop end signal = /mswin|mingw/ =~ RUBY_PLATFORM ? :INT : :TERM diff --git a/test/ruby/test_object.rb b/test/ruby/test_object.rb index 70dcd04201..61482f7c1a 100644 --- a/test/ruby/test_object.rb +++ b/test/ruby/test_object.rb @@ -690,6 +690,31 @@ class TestObject < Test::Unit::TestCase assert_equal(true, s.tainted?) end + def test_inspect + x = Object.new + assert_match(/\A#\z/, x.inspect) + + x.instance_variable_set(:@ivar, :value) + assert_match(/\A#\z/, x.inspect) + + x = Object.new + x.instance_variable_set(:@recur, x) + assert_match(/\A#>\z/, x.inspect) + + x = Object.new + x.instance_variable_set(:@foo, "value") + x.instance_variable_set(:@bar, 42) + assert_match(/\A#\z/, x.inspect) + + # #inspect does not call #to_s anymore + feature6130 = '[ruby-core:43238]' + x = Object.new + def x.to_s + "to_s" + end + assert_match(/\A#\z/, x.inspect, feature6130) + end + def test_exec_recursive Thread.current[:__recursive_key__] = nil a = [[]] diff --git a/test/test_pp.rb b/test/test_pp.rb index fe65287d88..acd3e835b9 100644 --- a/test/test_pp.rb +++ b/test/test_pp.rb @@ -118,7 +118,6 @@ class PPInspectTest < Test::Unit::TestCase def a.to_s() "aaa" end result = PP.pp(a, '') assert_equal("#{a.inspect}\n", result) - assert_equal("aaa\n", result) end end diff --git a/vm.c b/vm.c index 30d0f8a7bd..80dd512ae1 100644 --- a/vm.c +++ b/vm.c @@ -2229,6 +2229,7 @@ Init_top_self(void) vm->top_self = rb_obj_alloc(rb_cObject); rb_define_singleton_method(rb_vm_top_self(), "to_s", main_to_s, 0); + rb_define_alias(rb_singleton_class(rb_vm_top_self()), "inspect", "to_s"); /* initialize mark object array */ vm->mark_object_ary = rb_ary_tmp_new(1);