summaryrefslogtreecommitdiff
path: root/object.c
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2025-11-28 16:17:06 +0100
committerJean Boussier <jean.boussier@gmail.com>2025-11-28 18:34:59 +0100
commit191bfcb9c505ba3f5771f7ac67d6131aeb6b6837 (patch)
tree908014971b70e6994d367f9966bdda363347081c /object.c
parent8eaefd93951143661b1f515a8c9cda12263d2b56 (diff)
Define Kernel#instance_variables_to_inspect
[Bug #21718] Otherwise objects that don't define it, but define a fairly liberal `method_missing` method will run into errors that are hard to understand: ```ruby class Foo def method_missing(name, ...) name end end p Foo.new.inspect ``` ``` 'Kernel#inspect': wrong argument type Symbol (expected Array) (TypeError) from ../test.rb:7:in '<main>' ```
Diffstat (limited to 'object.c')
-rw-r--r--object.c21
1 files changed, 18 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 */