summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--object.c21
-rw-r--r--spec/ruby/core/kernel/inspect_spec.rb29
2 files changed, 47 insertions, 3 deletions
diff --git a/object.c b/object.c
index 097199479e..4b73fcefa8 100644
--- a/object.c
+++ b/object.c
@@ -854,14 +854,21 @@ rb_obj_inspect(VALUE obj)
{
VALUE ivars = rb_check_funcall(obj, id_instance_variables_to_inspect, 0, 0);
st_index_t n = 0;
- if (UNDEF_P(ivars)) {
+ if (UNDEF_P(ivars) || NIL_P(ivars)) {
n = rb_ivar_count(obj);
ivars = Qnil;
}
- else if (!NIL_P(ivars)) {
- Check_Type(ivars, T_ARRAY);
+ else if (RB_TYPE_P(ivars, T_ARRAY)) {
n = RARRAY_LEN(ivars);
}
+ else {
+ rb_raise(
+ rb_eTypeError,
+ "Expected #instance_variables_to_inspect to return an Array or nil, but it returned %"PRIsVALUE,
+ rb_obj_class(ivars)
+ );
+ }
+
if (n > 0) {
VALUE c = rb_class_name(CLASS_OF(obj));
VALUE args[2] = {
@@ -875,6 +882,13 @@ rb_obj_inspect(VALUE obj)
}
}
+/* :nodoc: */
+static VALUE
+rb_obj_instance_variables_to_inspect(VALUE obj)
+{
+ return Qnil;
+}
+
static VALUE
class_or_module_required(VALUE c)
{
@@ -4535,6 +4549,7 @@ InitVM_Object(void)
rb_define_method(rb_mKernel, "to_s", rb_any_to_s, 0);
rb_define_method(rb_mKernel, "inspect", rb_obj_inspect, 0);
+ rb_define_private_method(rb_mKernel, "instance_variables_to_inspect", rb_obj_instance_variables_to_inspect, 0);
rb_define_method(rb_mKernel, "methods", rb_obj_methods, -1); /* in class.c */
rb_define_method(rb_mKernel, "singleton_methods", rb_obj_singleton_methods, -1); /* in class.c */
rb_define_method(rb_mKernel, "protected_methods", rb_obj_protected_methods, -1); /* in class.c */
diff --git a/spec/ruby/core/kernel/inspect_spec.rb b/spec/ruby/core/kernel/inspect_spec.rb
index 6ecf1e1c8c..1fa66cab98 100644
--- a/spec/ruby/core/kernel/inspect_spec.rb
+++ b/spec/ruby/core/kernel/inspect_spec.rb
@@ -57,5 +57,34 @@ describe "Kernel#inspect" do
inspected = obj.inspect.sub(/^#<Object:0x[0-9a-f]+/, '#<Object:0x00')
inspected.should == "#<Object:0x00>"
end
+
+ it "displays all instance variables if #instance_variables_to_inspect returns nil" do
+ obj = Object.new
+ obj.instance_eval do
+ @host = "localhost"
+ @user = "root"
+ @password = "hunter2"
+ end
+ obj.singleton_class.class_eval do
+ private def instance_variables_to_inspect = nil
+ end
+
+ inspected = obj.inspect.sub(/^#<Object:0x[0-9a-f]+/, '#<Object:0x00')
+ inspected.should == %{#<Object:0x00 @host="localhost", @user="root", @password="hunter2">}
+ end
+
+ it "raises an error if #instance_variables_to_inspect returns an invalid value" do
+ obj = Object.new
+ obj.instance_eval do
+ @host = "localhost"
+ @user = "root"
+ @password = "hunter2"
+ end
+ obj.singleton_class.class_eval do
+ private def instance_variables_to_inspect = {}
+ end
+
+ ->{ obj.inspect }.should raise_error(TypeError, "Expected #instance_variables_to_inspect to return an Array or nil, but it returned Hash")
+ end
end
end