mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Kernel#inspect: improve consistency and do not call #to_s.
* 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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36709 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
e272790d11
commit
fd7dc23d28
12 changed files with 72 additions and 39 deletions
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
||||||
|
Wed Aug 15 20:47:49 2012 Benoit Daloze <eregontp@gmail.com>
|
||||||
|
|
||||||
|
* 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 <usa@ruby-lang.org>
|
Wed Aug 15 18:05:37 2012 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
* lib/test/unit.rb (Test::Unit::Runner#failed): need to delete the
|
* lib/test/unit.rb (Test::Unit::Runner#failed): need to delete the
|
||||||
|
|
2
NEWS
2
NEWS
|
@ -46,6 +46,8 @@ with all sufficient information, see the ChangeLog file.
|
||||||
* __callee__ has returned to the original behavior, and now
|
* __callee__ has returned to the original behavior, and now
|
||||||
returns the called name but not the original name in an
|
returns the called name but not the original name in an
|
||||||
aliased method.
|
aliased method.
|
||||||
|
* Kernel#inspect does not call #to_s anymore
|
||||||
|
(it used to call redefined #to_s).
|
||||||
|
|
||||||
* LoadError
|
* LoadError
|
||||||
* added method:
|
* added method:
|
||||||
|
|
1
bignum.c
1
bignum.c
|
@ -3835,6 +3835,7 @@ Init_Bignum(void)
|
||||||
rb_cBignum = rb_define_class("Bignum", rb_cInteger);
|
rb_cBignum = rb_define_class("Bignum", rb_cInteger);
|
||||||
|
|
||||||
rb_define_method(rb_cBignum, "to_s", rb_big_to_s, -1);
|
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, "coerce", rb_big_coerce, 1);
|
||||||
rb_define_method(rb_cBignum, "-@", rb_big_uminus, 0);
|
rb_define_method(rb_cBignum, "-@", rb_big_uminus, 0);
|
||||||
rb_define_method(rb_cBignum, "+", rb_big_plus, 1);
|
rb_define_method(rb_cBignum, "+", rb_big_plus, 1);
|
||||||
|
|
1
io.c
1
io.c
|
@ -11505,6 +11505,7 @@ Init_IO(void)
|
||||||
rb_define_method(rb_cARGF, "initialize", argf_initialize, -2);
|
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, "initialize_copy", argf_initialize_copy, 1);
|
||||||
rb_define_method(rb_cARGF, "to_s", argf_to_s, 0);
|
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, "argv", argf_argv, 0);
|
||||||
|
|
||||||
rb_define_method(rb_cARGF, "fileno", argf_fileno, 0);
|
rb_define_method(rb_cARGF, "fileno", argf_fileno, 0);
|
||||||
|
|
11
lib/pp.rb
11
lib/pp.rb
|
@ -265,8 +265,7 @@ class PP < PrettyPrint
|
||||||
module ObjectMixin
|
module ObjectMixin
|
||||||
# 1. specific pretty_print
|
# 1. specific pretty_print
|
||||||
# 2. specific inspect
|
# 2. specific inspect
|
||||||
# 3. specific to_s
|
# 3. generic pretty_print
|
||||||
# 4. generic pretty_print
|
|
||||||
|
|
||||||
# A default pretty printing method for general objects.
|
# A default pretty printing method for general objects.
|
||||||
# It calls #pretty_print_instance_variables to list instance variables.
|
# It calls #pretty_print_instance_variables to list instance variables.
|
||||||
|
@ -283,18 +282,10 @@ class PP < PrettyPrint
|
||||||
inspect_method = method_method.call(:inspect)
|
inspect_method = method_method.call(:inspect)
|
||||||
rescue NameError
|
rescue NameError
|
||||||
end
|
end
|
||||||
begin
|
|
||||||
to_s_method = method_method.call(:to_s)
|
|
||||||
rescue NameError
|
|
||||||
end
|
|
||||||
if inspect_method && /\(Kernel\)#/ !~ inspect_method.inspect
|
if inspect_method && /\(Kernel\)#/ !~ inspect_method.inspect
|
||||||
q.text self.inspect
|
q.text self.inspect
|
||||||
elsif !inspect_method && self.respond_to?(:inspect)
|
elsif !inspect_method && self.respond_to?(:inspect)
|
||||||
q.text self.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
|
else
|
||||||
q.pp_object(self)
|
q.pp_object(self)
|
||||||
end
|
end
|
||||||
|
|
|
@ -3660,6 +3660,7 @@ Init_Numeric(void)
|
||||||
rb_cFixnum = rb_define_class("Fixnum", rb_cInteger);
|
rb_cFixnum = rb_define_class("Fixnum", rb_cInteger);
|
||||||
|
|
||||||
rb_define_method(rb_cFixnum, "to_s", fix_to_s, -1);
|
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_uminus, 0);
|
||||||
rb_define_method(rb_cFixnum, "+", fix_plus, 1);
|
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_const(rb_cFloat, "NAN", DBL2NUM(NAN));
|
||||||
|
|
||||||
rb_define_method(rb_cFloat, "to_s", flo_to_s, 0);
|
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, "coerce", flo_coerce, 1);
|
||||||
rb_define_method(rb_cFloat, "-@", flo_uminus, 0);
|
rb_define_method(rb_cFloat, "-@", flo_uminus, 0);
|
||||||
rb_define_method(rb_cFloat, "+", flo_plus, 1);
|
rb_define_method(rb_cFloat, "+", flo_plus, 1);
|
||||||
|
|
38
object.c
38
object.c
|
@ -450,11 +450,8 @@ inspect_obj(VALUE obj, VALUE str, int recur)
|
||||||
* obj.inspect -> string
|
* obj.inspect -> string
|
||||||
*
|
*
|
||||||
* Returns a string containing a human-readable representation of <i>obj</i>.
|
* 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
|
* By default, show the class name and the list of the instance variables and
|
||||||
* and instance variable details which is the list of the name and the result
|
* their values (by calling #inspect on each of them).
|
||||||
* 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.
|
|
||||||
* User defined classes should override this method to make better
|
* User defined classes should override this method to make better
|
||||||
* representation of <i>obj</i>. When overriding this method, it should
|
* representation of <i>obj</i>. When overriding this method, it should
|
||||||
* return a string whose encoding is compatible with the default external
|
* return a string whose encoding is compatible with the default external
|
||||||
|
@ -479,35 +476,21 @@ inspect_obj(VALUE obj, VALUE str, int recur)
|
||||||
* "baz"
|
* "baz"
|
||||||
* end
|
* end
|
||||||
* end
|
* end
|
||||||
* Baz.new.inspect #=> "baz"
|
* Baz.new.inspect #=> "#<Baz:0x0300c868>"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_obj_inspect(VALUE obj)
|
rb_obj_inspect(VALUE obj)
|
||||||
{
|
{
|
||||||
if (RB_TYPE_P(obj, T_OBJECT) && rb_obj_basic_to_s_p(obj)) {
|
if (rb_ivar_count(obj) > 0) {
|
||||||
int has_ivar = 0;
|
VALUE str;
|
||||||
VALUE *ptr = ROBJECT_IVPTR(obj);
|
const char *c = rb_obj_classname(obj);
|
||||||
long len = ROBJECT_NUMIV(obj);
|
|
||||||
long i;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
str = rb_sprintf("-<%s:%p", c, (void*)obj);
|
||||||
if (ptr[i] != Qundef) {
|
return rb_exec_recursive(inspect_obj, obj, str);
|
||||||
has_ivar = 1;
|
} else {
|
||||||
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);
|
|
||||||
}
|
|
||||||
return rb_any_to_s(obj);
|
return rb_any_to_s(obj);
|
||||||
}
|
}
|
||||||
return rb_funcall(obj, rb_intern("to_s"), 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -2951,6 +2934,7 @@ Init_Object(void)
|
||||||
rb_define_method(rb_cModule, ">=", rb_mod_ge, 1);
|
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, "initialize_copy", rb_mod_init_copy, 1); /* in class.c */
|
||||||
rb_define_method(rb_cModule, "to_s", rb_mod_to_s, 0);
|
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, "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, "include?", rb_mod_include_p, 1); /* in class.c */
|
||||||
rb_define_method(rb_cModule, "name", rb_mod_name, 0); /* in variable.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_cTrueClass = rb_define_class("TrueClass", rb_cObject);
|
||||||
rb_define_method(rb_cTrueClass, "to_s", true_to_s, 0);
|
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_and, 1);
|
||||||
rb_define_method(rb_cTrueClass, "|", true_or, 1);
|
rb_define_method(rb_cTrueClass, "|", true_or, 1);
|
||||||
rb_define_method(rb_cTrueClass, "^", true_xor, 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_cFalseClass = rb_define_class("FalseClass", rb_cObject);
|
||||||
rb_define_method(rb_cFalseClass, "to_s", false_to_s, 0);
|
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_and, 1);
|
||||||
rb_define_method(rb_cFalseClass, "|", false_or, 1);
|
rb_define_method(rb_cFalseClass, "|", false_or, 1);
|
||||||
rb_define_method(rb_cFalseClass, "^", false_xor, 1);
|
rb_define_method(rb_cFalseClass, "^", false_xor, 1);
|
||||||
|
|
1
proc.c
1
proc.c
|
@ -2217,6 +2217,7 @@ Init_Proc(void)
|
||||||
rb_define_method(rb_cProc, "eql?", proc_eq, 1);
|
rb_define_method(rb_cProc, "eql?", proc_eq, 1);
|
||||||
rb_define_method(rb_cProc, "hash", proc_hash, 0);
|
rb_define_method(rb_cProc, "hash", proc_hash, 0);
|
||||||
rb_define_method(rb_cProc, "to_s", proc_to_s, 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, "lambda?", rb_proc_lambda_p, 0);
|
||||||
rb_define_method(rb_cProc, "binding", proc_binding, 0);
|
rb_define_method(rb_cProc, "binding", proc_binding, 0);
|
||||||
rb_define_method(rb_cProc, "curry", proc_curry, -1);
|
rb_define_method(rb_cProc, "curry", proc_curry, -1);
|
||||||
|
|
|
@ -73,7 +73,7 @@ module DRbCore
|
||||||
def teardown
|
def teardown
|
||||||
@ext.stop_service if defined?(@ext) && @ext
|
@ext.stop_service if defined?(@ext) && @ext
|
||||||
DRbService.manager.unregist(@service_name)
|
DRbService.manager.unregist(@service_name)
|
||||||
while (@there.inspect rescue nil)
|
while (@there.to_s rescue nil)
|
||||||
# nop
|
# nop
|
||||||
end
|
end
|
||||||
signal = /mswin|mingw/ =~ RUBY_PLATFORM ? :INT : :TERM
|
signal = /mswin|mingw/ =~ RUBY_PLATFORM ? :INT : :TERM
|
||||||
|
@ -294,7 +294,7 @@ module DRbAry
|
||||||
def teardown
|
def teardown
|
||||||
@ext.stop_service if defined?(@ext) && @ext
|
@ext.stop_service if defined?(@ext) && @ext
|
||||||
DRbService.manager.unregist(@service_name)
|
DRbService.manager.unregist(@service_name)
|
||||||
while (@there.inspect rescue nil)
|
while (@there.to_s rescue nil)
|
||||||
# nop
|
# nop
|
||||||
end
|
end
|
||||||
signal = /mswin|mingw/ =~ RUBY_PLATFORM ? :INT : :TERM
|
signal = /mswin|mingw/ =~ RUBY_PLATFORM ? :INT : :TERM
|
||||||
|
|
|
@ -690,6 +690,31 @@ class TestObject < Test::Unit::TestCase
|
||||||
assert_equal(true, s.tainted?)
|
assert_equal(true, s.tainted?)
|
||||||
end
|
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
|
def test_exec_recursive
|
||||||
Thread.current[:__recursive_key__] = nil
|
Thread.current[:__recursive_key__] = nil
|
||||||
a = [[]]
|
a = [[]]
|
||||||
|
|
|
@ -118,7 +118,6 @@ class PPInspectTest < Test::Unit::TestCase
|
||||||
def a.to_s() "aaa" end
|
def a.to_s() "aaa" end
|
||||||
result = PP.pp(a, '')
|
result = PP.pp(a, '')
|
||||||
assert_equal("#{a.inspect}\n", result)
|
assert_equal("#{a.inspect}\n", result)
|
||||||
assert_equal("aaa\n", result)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
1
vm.c
1
vm.c
|
@ -2229,6 +2229,7 @@ Init_top_self(void)
|
||||||
|
|
||||||
vm->top_self = rb_obj_alloc(rb_cObject);
|
vm->top_self = rb_obj_alloc(rb_cObject);
|
||||||
rb_define_singleton_method(rb_vm_top_self(), "to_s", main_to_s, 0);
|
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 */
|
/* initialize mark object array */
|
||||||
vm->mark_object_ary = rb_ary_tmp_new(1);
|
vm->mark_object_ary = rb_ary_tmp_new(1);
|
||||||
|
|
Loading…
Reference in a new issue