aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-08-14 10:20:44 +0000
committereregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-08-14 10:20:44 +0000
commit795c29dcda01fa81a3ccebee4433adabe6778d76 (patch)
treef2793f0ffc75a3292d7276ef087ca20cfd0d6e02
parentf42a7c09513b5f73e21e6fae881f3bc2f760b9af (diff)
downloadruby-795c29dcda01fa81a3ccebee4433adabe6778d76.tar.gz
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
-rw-r--r--ChangeLog15
-rw-r--r--bignum.c1
-rw-r--r--io.c1
-rw-r--r--numeric.c2
-rw-r--r--object.c38
-rw-r--r--proc.c1
-rw-r--r--test/ruby/test_object.rb25
-rw-r--r--vm.c1
8 files changed, 58 insertions, 26 deletions
diff --git a/ChangeLog b/ChangeLog
index fc8ae2c2a9..ff36a15df8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+Tue Aug 14 19:09:38 2012 Benoit Daloze <eregontp@gmail.com>
+
+ 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]
+
Tue Aug 14 16:25:46 2012 Shugo Maeda <shugo@ruby-lang.org>
* test/erb/test_erb.rb (test_html_escape): add assertions for the
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/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 <i>obj</i>.
- * By default, if the <i>obj</i> has instance variables, show the class name
- * and instance variable details which is the list of the name and the result
- * of <i>inspect</i> method for each instance variable.
- * Otherwise uses the <i>to_s</i> method to generate the string.
- * If the <i>to_s</i> 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 <i>obj</i>. 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 #=> "#<Baz:0x0300c868>"
*/
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);
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/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#<Object:0x\h+>\z/, x.inspect)
+
+ x.instance_variable_set(:@ivar, :value)
+ assert_match(/\A#<Object:0x\h+ @ivar=:value>\z/, x.inspect)
+
+ x = Object.new
+ x.instance_variable_set(:@recur, x)
+ assert_match(/\A#<Object:0x\h+ @recur=#<Object:0x\h+ \.\.\.>>\z/, x.inspect)
+
+ x = Object.new
+ x.instance_variable_set(:@foo, "value")
+ x.instance_variable_set(:@bar, 42)
+ assert_match(/\A#<Object:0x\h+ (?:@foo="value", @bar=42|@bar=42, @foo="value")>\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#<Object:0x\h+>\z/, x.inspect, feature6130)
+ end
+
def test_exec_recursive
Thread.current[:__recursive_key__] = nil
a = [[]]
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);