Description
Reference#inspect
and Struct#inspect
iterate over all instance variables, printing them one by one. There are some cases where we do not want every single instance variable shown:
- The field contains sensitive information. (You should not hold these objects in memory for too long, either way.)
- The field is strictly unused, for example it solely exists to control member alignment. This is common in C, e.g. most of our bindings for
LibC::Stat
contain a few of these fields. - The field is part of an encompassing data structure, in particular it could be the adjacent node(s) in an intrusive linked list; inspecting one node would end up printing out the rest of the entire chain of nodes.
#15829 is an example where #inspect
is explicitly overridden to handle the last case. Doing so, however, requires consciously replicating the logic in the base implementation, or using a different output format altogether. It would be great if the standard library offers some flexibility in controlling the output exactly as we wanted.
In a nod to the serialization support in the standard library, I am proposing an Object::Field
instance variable annotation that accepts an ignore
named argument. If this argument is true
, then the default #inspect
will not print this instance variable:
annotation Object::Field
end
class Foo
@x = 1
@[Object::Field(ignore: true)]
@y = 2
@z = 3
@[Field(ignore: true)]
protected getter password = "foo"
end
Foo.new # => #<Foo:0x10318afa0 @x=1, @z=3>
This could be extended to #pretty_print
too. The annotation is open for future extensions; for example, it might have a different parameter controlling whether the instance variable is accessed in the default Struct#==
and #hash
, useful for the padding fields described above.
A potential problem of the naming is that you don't need the Object::
part of the name and actually just @[Field]
will do, because almost every type inherits from Object
.