diff options
| author | Jean Boussier <jean.boussier@gmail.com> | 2025-11-28 16:17:06 +0100 |
|---|---|---|
| committer | Jean Boussier <jean.boussier@gmail.com> | 2025-11-28 18:34:59 +0100 |
| commit | 191bfcb9c505ba3f5771f7ac67d6131aeb6b6837 (patch) | |
| tree | 908014971b70e6994d367f9966bdda363347081c /object.c | |
| parent | 8eaefd93951143661b1f515a8c9cda12263d2b56 (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.c | 21 |
1 files changed, 18 insertions, 3 deletions
@@ -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 */ |
