Bug #21718
openTypeError:wrong argument type ... (expected Array)
Description
Testing Ruby 4.0 on Fedora, we observe these errors in MiniMagick
1) MiniMagick::Image#composite yields an optional block
Failure/Error: yield composite if block_given?
TypeError:
wrong argument type MiniMagick::Tool (expected Array)
# ./lib/mini_magick/image.rb:515:in 'block in MiniMagick::Image#composite'
# ./lib/mini_magick/tool.rb:34:in 'MiniMagick::Tool.new'
# ./lib/mini_magick.rb:28:in 'block (2 levels) in module:MiniMagick'
# ./lib/mini_magick/image.rb:514:in 'MiniMagick::Image#composite'
# ./spec/lib/mini_magick/image_spec.rb:609:in 'block (4 levels) in <top (required)>'
# ./spec/lib/mini_magick/image_spec.rb:610:in 'block (3 levels) in <top (required)>'
and Vagrant / vagrant-libvirt
340) VagrantPlugins::ProviderLibvirt::Util::NetworkUtil #libvirt_networks should retrieve the list of networks
Failure/Error: let(:machine) { iso_env.machine(:test, :libvirt) }
TypeError:
wrong argument type Vagrant::Config::V2::DummyConfig (expected Array)
# /usr/share/vagrant/gems/gems/vagrant-2.3.4/plugins/kernel_v2/config/vm.rb:713:in 'Kernel#inspect'
# /usr/share/vagrant/gems/gems/vagrant-2.3.4/plugins/kernel_v2/config/vm.rb:713:in 'VagrantPlugins::Kernel_V2::VMConfig#get_provider_config'
# /usr/share/vagrant/gems/gems/vagrant-2.3.4/lib/vagrant/vagrantfile.rb:75:in 'Vagrant::Vagrantfile#machine'
# /usr/share/vagrant/gems/gems/vagrant-2.3.4/lib/vagrant/environment.rb:740:in 'Vagrant::Environment#machine'
# ./spec/support/unit_context.rb:26:in 'block (2 levels) in <top (required)>'
# ./spec/support/unit_context.rb:37:in 'block (2 levels) in <top (required)>'
# ./spec/support/unit_context.rb:51:in 'block (3 levels) in <top (required)>'
# ./spec/support/unit_context.rb:43:in 'block (2 levels) in <top (required)>'
# /usr/share/rubygems/rubygems.rb:303:in 'Kernel#load'
# /usr/share/rubygems/rubygems.rb:303:in 'Gem.activate_and_load_bin_path'
Trying to investigate closer the vagrant-libvirt case, I really cannot wrap my head around it, because it fails with innocently looking result.inspect 1. The image_magick fails at yield composite if block_given? line, so I suspect that the yield composite is the specific place.
Since this does not make any sense to me, I have grepped the Ruby source code for:
$ grep -R -e TypeError | grep "wrong argument type.*Array"
... snip ...
prism/extension.c: rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Array)", rb_obj_class(scopes));
prism/extension.c: rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Array)", rb_obj_class(locals));
prism/extension.c: rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Array)", rb_obj_class(names));
This seems to come from https://github.com/ruby/prism/commit/21abb6b7c499b41a951eba7c8219c336a656da40 . So is it the reason? Not sure.
Updated by Earlopain (Earlopain _) about 4 hours ago
ยท Edited
I only checked minimagick, this looks caused by https://bugs.ruby-lang.org/issues/21219
MiniMagick::Tool defines method_missing and returns itself: https://github.com/minimagick/minimagick/blob/ddcbfe9632667876be10373e1e01252617e74057/lib/mini_magick/tool.rb#L257-L262
The test passes if I explicitly return an array on like return [] if name == :instance_variables_to_inspect. Rspec code is not comprehensible to me but it looks like it might use inspect to match yielded arguments or something along those lines?
Basically, it boils down to this:
class Foo
def method_missing(...)
self
end
end
Foo.new.inspect # 'Kernel#inspect': wrong argument type Foo (expected Array) (TypeError)
Even just calling method_missing would break minimagick tests, so practically you would also always need to implement instance_variables_to_inspect for correctness or risk being broken by inspect. So not raising on unexpected types in inspect would not really help and just move the error someplace else. Skipping method_missing for instance_variables_to_inspect (needing it to be explicitly defined) could work but seems a bit unexpected?
Updated by mtasaka (Mamoru TASAKA) about 3 hours ago
it looks like it might use inspect to match yielded arguments or something along those lines?
Maybe to_s calls inspect?
Updated by vo.x (Vit Ondruch) about 2 hours ago
I only checked minimagick, this looks caused by https://bugs.ruby-lang.org/issues/21219
Yep, I think so.
I have just tried to add p composite on this place and this seems to be the BT where it gets wrong:
(gdb) call (void) rb_backtrace()
from /usr/bin/rspec:25:in '<main>'
from /usr/bin/rspec:25:in 'load'
from /usr/share/gems/gems/rspec-core-3.13.6/exe/rspec:4:in '<top (required)>'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb:45:in 'invoke'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb:71:in 'run'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb:89:in 'run'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb:115:in 'run_specs'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/reporter.rb:74:in 'report'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb:116:in 'block in run_specs'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/configuration.rb:2097:in 'with_suite_hooks'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb:121:in 'block (2 levels) in run_specs'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb:121:in 'map'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/runner.rb:121:in 'block (3 levels) in run_specs'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb:615:in 'run'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb:615:in 'map'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb:615:in 'block in run'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb:614:in 'run'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb:649:in 'run_examples'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb:649:in 'map'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example_group.rb:653:in 'block in run_examples'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example.rb:259:in 'run'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example.rb:511:in 'with_around_and_singleton_context_hooks'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example.rb:468:in 'with_around_example_hooks'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/hooks.rb:486:in 'run'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/hooks.rb:624:in 'run_around_example_hooks_for'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/hooks.rb:486:in 'block in run'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example.rb:468:in 'block in with_around_example_hooks'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example.rb:511:in 'block in with_around_and_singleton_context_hooks'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example.rb:263:in 'block in run'
from /usr/share/gems/gems/rspec-core-3.13.6/lib/rspec/core/example.rb:263:in 'instance_exec'
from /builddir/build/BUILD/rubygem-mini_magick-5.3.1-build/mini_magick-5.3.1/usr/share/gems/gems/mini_magick-5.3.1/spec/lib/mini_magick/image_spec.rb:610:in 'block (3 levels) in <top (required)>'
from /usr/share/gems/gems/rspec-expectations-3.13.5/lib/rspec/expectations/expectation_target.rb:139:in 'to'
from /usr/share/gems/gems/rspec-expectations-3.13.5/lib/rspec/expectations/expectation_target.rb:65:in 'to'
from /usr/share/gems/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb:47:in 'handle_matcher'
from /usr/share/gems/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb:26:in 'with_matcher'
from /usr/share/gems/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb:50:in 'block in handle_matcher'
from /usr/share/gems/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/yield.rb:213:in 'matches?'
from /usr/share/gems/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/yield.rb:35:in 'probe'
from /builddir/build/BUILD/rubygem-mini_magick-5.3.1-build/mini_magick-5.3.1/usr/share/gems/gems/mini_magick-5.3.1/spec/lib/mini_magick/image_spec.rb:609:in 'block (4 levels) in <top (required)>'
from /builddir/build/BUILD/rubygem-mini_magick-5.3.1-build/mini_magick-5.3.1/usr/share/gems/gems/mini_magick-5.3.1/lib/mini_magick/image.rb:514:in 'composite'
from /builddir/build/BUILD/rubygem-mini_magick-5.3.1-build/mini_magick-5.3.1/usr/share/gems/gems/mini_magick-5.3.1/lib/mini_magick.rb:28:in 'block (2 levels) in <module:MiniMagick>'
from /builddir/build/BUILD/rubygem-mini_magick-5.3.1-build/mini_magick-5.3.1/usr/share/gems/gems/mini_magick-5.3.1/lib/mini_magick/tool.rb:34:in 'new'
from /builddir/build/BUILD/rubygem-mini_magick-5.3.1-build/mini_magick-5.3.1/usr/share/gems/gems/mini_magick-5.3.1/lib/mini_magick/image.rb:516:in 'block in composite'
from /builddir/build/BUILD/rubygem-mini_magick-5.3.1-build/mini_magick-5.3.1/usr/share/gems/gems/mini_magick-5.3.1/lib/mini_magick/image.rb:516:in 'p'
from /builddir/build/BUILD/rubygem-mini_magick-5.3.1-build/mini_magick-5.3.1/usr/share/gems/gems/mini_magick-5.3.1/lib/mini_magick/image.rb:516:in 'inspect'
(gdb) bt
#0 ruby__sfvextra (fp=0x7fffffffc480, valsize=<optimized out>, valp=0x7fffffffbe18, sz=0x7fffffffbe20, sign=0) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/sprintf.c:1125
#1 0x00007ffff7a0ff19 in BSD_vfprintf (fp=fp@entry=0x7fffffffc480, fmt0=fmt0@entry=0x7ffff7c65a10 "wrong argument type %li\v (expected %s)", ap=ap@entry=0x7fffffffc540)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vsnprintf.c:830
#2 0x00007ffff7a1172a in ruby_vsprintf0 (result=result@entry=140737340003120, p=0x7ffff7285348 "wrong argument type ", fmt=fmt@entry=0x7ffff7c65a10 "wrong argument type %li\v (expected %s)",
ap=ap@entry=0x7fffffffc540) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/sprintf.c:1164
#3 0x00007ffff7a11829 in rb_enc_vsprintf (enc=enc@entry=0x0, fmt=0x7ffff7c65a10 "wrong argument type %li\v (expected %s)", ap=ap@entry=0x7fffffffc540)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/include/ruby/internal/core/rstring.h:397
#4 0x00007ffff7a11931 in rb_vsprintf (fmt=<optimized out>, ap=ap@entry=0x7fffffffc540) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/sprintf.c:1213
#5 0x00007ffff7a119e1 in rb_sprintf (format=<optimized out>) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/sprintf.c:1223
#6 0x00007ffff7808dfc in unexpected_type (x=x@entry=140736882595640, xt=<optimized out>, t=t@entry=7) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/error.c:1322
#7 0x00007ffff7808e9b in rb_unexpected_type (x=140736882595640, t=7) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/error.c:1366
#8 0x00007ffff780ada5 in Check_Type (v=<optimized out>, t=RUBY_T_ARRAY) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/include/ruby/internal/value_type.h:447
#9 rb_obj_inspect (obj=140736882595640) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/object.c:862
#10 0x00007ffff7a9d570 in vm_call0_cfunc_with_frame (ec=0x555555561080, calling=<optimized out>, argv=<optimized out>)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_eval.c:164
#11 vm_call0_cfunc (ec=0x555555561080, calling=<optimized out>, argv=<optimized out>) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_eval.c:178
#12 vm_call0_body (ec=0x555555561080, calling=<optimized out>, argv=<optimized out>) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_eval.c:229
#13 0x00007ffff7aa18aa in vm_call0_cc (ec=0x555555561080, recv=140736882595640, id=2801, argc=0, argv=<optimized out>, cc=<optimized out>, kw_splat=0)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_eval.c:101
#14 rb_funcallv_scope (recv=140736882595640, mid=2801, argc=0, argv=<optimized out>, scope=CALL_FCALL) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_eval.c:1065
#15 rb_funcallv (recv=140736882595640, mid=2801, argc=0, argv=<optimized out>) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_eval.c:1080
#16 0x00007ffff7961509 in rb_inspect (obj=<optimized out>) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/object.c:748
#17 0x00007ffff791851c in rb_f_p (argc=1, argv=0x7ffff73f8760, self=<optimized out>) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/io.c:9093
#18 0x00007ffff7a8669e in vm_call_cfunc_with_frame_ (ec=0x555555561080, reg_cfp=0x7ffff74f7670, calling=<optimized out>, argc=1, argv=<optimized out>, stack_bottom=<optimized out>)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_insnhelper.c:3915
#19 0x00007ffff7a90095 in vm_sendish (ec=<optimized out>, reg_cfp=<optimized out>, cd=<optimized out>, block_handler=<optimized out>, method_explorer=<optimized out>)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_insnhelper.c:6134
#20 vm_exec_core (ec=0x7ffff72bf468) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/redhat-linux-build/insns.def:902
#21 0x00007ffff7aa7a5f in vm_exec_loop (ec=<optimized out>, state=<optimized out>, tag=<optimized out>, result=<optimized out>)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm.c:2811
#22 rb_vm_exec (ec=0x555555561080) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm.c:2787
#23 0x00007ffff7aaa730 in vm_yield_with_cref (ec=0x555555561080, argc=1, argv=0x7ffff73f84d8, kw_splat=0, cref=<optimized out>, is_lambda=0)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm.c:1865
#24 yield_under (self=<optimized out>, singleton=<optimized out>, argc=1, argv=0x7ffff73f84d8, kw_splat=0) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_eval.c:2218
#25 0x00007ffff7a8669e in vm_call_cfunc_with_frame_ (ec=0x555555561080, reg_cfp=0x7ffff74f7980, calling=<optimized out>, argc=1, argv=<optimized out>, stack_bottom=<optimized out>)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_insnhelper.c:3915
#26 0x00007ffff7a8c1c8 in vm_sendish (ec=<optimized out>, reg_cfp=<optimized out>, cd=<optimized out>, block_handler=<optimized out>, method_explorer=<optimized out>)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_callinfo.h:437
#27 0x00007ffff7a90af2 in vm_exec_core (ec=0x7ffff72bf468) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/redhat-linux-build/insns.def:854
#28 0x00007ffff7aa7a5f in vm_exec_loop (ec=<optimized out>, state=<optimized out>, tag=<optimized out>, result=<optimized out>)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm.c:2811
#29 rb_vm_exec (ec=0x555555561080) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm.c:2787
#30 0x00007ffff7aaad3f in vm_yield_with_cref (ec=<optimized out>, argc=1, argv=0x7fffffffd078, kw_splat=0, cref=0x0, is_lambda=0)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm.c:1865
#31 vm_yield (ec=<optimized out>, argc=1, argv=0x7fffffffd078, kw_splat=0) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm.c:1873
#32 rb_yield_0 (argc=1, argv=0x7fffffffd078) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_eval.c:1362
#33 rb_yield (val=<optimized out>) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_eval.c:1378
#34 0x00007ffff7820c4d in rb_ary_collect (ary=140736883800480) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/array.c:3673
#35 0x00007ffff7a8669e in vm_call_cfunc_with_frame_ (ec=0x555555561080, reg_cfp=0x7ffff74f7be8, calling=<optimized out>, argc=0, argv=<optimized out>, stack_bottom=<optimized out>)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_insnhelper.c:3915
#36 0x00007ffff7a8c1c8 in vm_sendish (ec=<optimized out>, reg_cfp=<optimized out>, cd=<optimized out>, block_handler=<optimized out>, method_explorer=<optimized out>)
at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/vm_callinfo.h:437
#37 0x00007ffff7a90af2 in vm_exec_core (ec=0x7ffff72bf468) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/redhat-linux-build/insns.def:854
#38 0x00007ffff7aa7a5f in vm_exec_loop (ec=<optimized out>, state=<optimized out>, tag=<optimized out>, result=<optimized out>)
--Type <RET> for more, q to quit, c to continue without paging--q
Quit
(gdb) f 9
#9 rb_obj_inspect (obj=140736882595640) at /usr/src/debug/ruby-4.0.0~20251118.0917git85abc59c32-28.fc44.251118.07.x86_64/object.c:862
862 Check_Type(ivars, T_ARRAY);
Updated by vo.x (Vit Ondruch) 42 minutes ago
To me, it seems that the VALUE ivars = rb_check_funcall(obj, id_instance_variables_to_inspect, 0, 0); code at rb_obj_inspect assumes that there is returned either nil or Array of symbols. But with method_missing available, it can essentially return anything and in the case of MiniMagick, there is returned MiniMagick::Tool (it could even be array of something else then symbols, what would happen in such case?).
IOW it seems that this feature implies that whenever method_missing is defined, it needs to take care about instance_variables_to_inspect. But that does not sound reasonable behavior to me.
Updated by vo.x (Vit Ondruch) 35 minutes ago
This is essentially what happens:
$ irb
irb(main):001* class Foo
irb(main):002* def initialize
irb(main):003* @bar = "bar"
irb(main):004* end
irb(main):005> end
=> :initialize
irb(main):006> Foo.new.inspect
=> "#<Foo:0x00007fe55b5f7c18 @bar=\"bar\">"
irb(main):007* class Foo
irb(main):008* def instance_variables_to_inspect = Object.new
irb(main):009> end
=> :instance_variables_to_inspect
irb(main):010> Foo.new.inspect
(irb):10:in 'Kernel#inspect': wrong argument type Object (expected Array) (TypeError)
from (irb):10:in '<main>'
from /usr/share/gems/gems/irb-1.14.3/exe/irb:9:in '<top (required)>'
from /usr/bin/irb:25:in 'Kernel#load'
from /usr/bin/irb:25:in '<main>'
But if the method_missing should somehow treat the nonexistence of instance_variables_to_inspect is also interesting question
Updated by luke-gru (Luke Gruber) 29 minutes ago
Ignoring method_missing in this case or wrapping the non-array object in an array are the only workarounds I can think of. I don't believe ruby ever ignores method_missing like this, so it would be a bit different to do it here.
Updated by byroot (Jean Boussier) 11 minutes ago
I agree we shouldn't fallback to method_missing when checking for instance_variables_to_inspect. Not fully sure how to do that though.
Updated by vo.x (Vit Ondruch) 7 minutes ago
In retrospect, is the instance_variables_to_inspect design good? Wouldn't it be better if such method behaved as some filter? E.g. it would get e.g. an array of something (maybe list of instance variables?), which could be altered and returned afterwards? And maybe such method should be always defined, to prevent surprises with method_missing? Just thinking loud ...