-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve documentation for Object#to_s
and #inspect
#9974
Improve documentation for Object#to_s
and #inspect
#9974
Conversation
This patch changes the method definitions as proposed in crystal-lang#9966 and adds some additional notes. The part about ambigouity of collection members is removed because that's not generically relevant for `#inspect` but for individual implementations such as `Array#inspect`. So I added a short note about it there. It does not need to be repeated for every collection type.
@@ -1930,6 +1930,17 @@ class Array(T) | |||
self | |||
end | |||
|
|||
# Prints a nicely readable and concise string representation of this array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Prints a nicely readable and concise string representation of this array | |
# Prints a readable and concise string representation of this array |
Let's avoid subjective language :) Ditto all the other instances.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think "nicely" fits very well here. Just "readable" doesn't cut it. Of course, it should be readable. But so does #inspect
. This one should be a nice, informal representation.
src/object.cr
Outdated
# identical environment) is an ideal representation. It doesn't need to be | ||
# actual code that compiles, but a resemblance is recommended. | ||
# When this is not possible (for example for non-printable internal state) | ||
# another useful description will do. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's be honest, this is a lie. It's true for literal'ish values, but beyond that the representation never even tries represent valid code. The default implementations for Reference
and Struct
make a good example of my point here. You wouldn't want the inspect
representation to be like SomeStruct.new(a: ..., b: ...)
as that's noisy and a little weird.
So I'm not sure this is true for people that are not standard library/compiler developers like us. You don't work much with "custom" objects that are literals elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the wording could be a bit relaxed, but in general I think it's a good idea to try to print Crystal expressions. That's concise and unambiguous. Struct#inspect
actually isn't far from Crystal code.
Simple structs/classes which are just containers for a vew ivars are already covered by the respective default implementations. These notes are particularly relevant for more advanced types. For example custom collection types. They can actually use array-like or hash-like literals. HTTP::Params{"foo" => "bar"}
would be a perfect inspect
representation. Currently, it's more bulky: HTTP::Params(@raw_params={"foo" => ["bar"]})
. That's an example from stdlib but you have such types in shards, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also not entirely happy with this wording, but it's more of style than anything else. Perhaps we can pick a couple of (good) examples from the stdlib instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't add a suggestion to the entire block, so here it goes in plain 🤷
# Prints to *io* an unambiguous and information-rich string representation of this
# object, typically intended for developers.
#
# It is similar to `#to_s(IO)`, but often provides more information. Ideally, it should
# contain sufficient information to be able to recreate an object with the same value
# (given an identical environment).
#
# For types that don't provide a custom implementation of this method,
# default implementation delegates to `#to_s(IO)`. This said, it is advisable to
# have an appropriate `#inspect` implementation on every type. Default
# implementations are provided by `Struct#inspect` and `Reference#inspect`.
#
# `::p` and `::p!` use this method to print an object in `STDOUT`.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @straight-shoota 🙏
src/object.cr
Outdated
# identical environment) is an ideal representation. It doesn't need to be | ||
# actual code that compiles, but a resemblance is recommended. | ||
# When this is not possible (for example for non-printable internal state) | ||
# another useful description will do. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also not entirely happy with this wording, but it's more of style than anything else. Perhaps we can pick a couple of (good) examples from the stdlib instead?
src/object.cr
Outdated
# Similar to `to_s(io)`, but usually appends more information | ||
# about this object. | ||
# See `#inspect`. | ||
# `::p` and `::p!` use this method to present an object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to have the ::
here? doc
doesn't resolve it correctly? More a curiosity than a request to change.
# `::p` and `::p!` use this method to present an object. | |
# `p` and `p!` use this method to present an object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah otherwise the docs generator wouldn't catch the reference to p
.
# | ||
# The result resembles an array literal but it does not necessarily compile. | ||
# | ||
# Each element is presented using its `#inspect(io)` result to avoid ambiguity. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we mention avoiding circular references here? Or perhaps some other wording that explains the ...
? The docs also serve for people writing overrides and I think catching circular references is important for those overriders to know about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we only have to revisit this if/when we consider making exec_recursive
a public API
Co-authored-by: Beta Ziliani <beta@manas.tech>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment for inspect
was still a bit odd for me. I rewrote it. WDYT?
src/object.cr
Outdated
# identical environment) is an ideal representation. It doesn't need to be | ||
# actual code that compiles, but a resemblance is recommended. | ||
# When this is not possible (for example for non-printable internal state) | ||
# another useful description will do. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't add a suggestion to the entire block, so here it goes in plain 🤷
# Prints to *io* an unambiguous and information-rich string representation of this
# object, typically intended for developers.
#
# It is similar to `#to_s(IO)`, but often provides more information. Ideally, it should
# contain sufficient information to be able to recreate an object with the same value
# (given an identical environment).
#
# For types that don't provide a custom implementation of this method,
# default implementation delegates to `#to_s(IO)`. This said, it is advisable to
# have an appropriate `#inspect` implementation on every type. Default
# implementations are provided by `Struct#inspect` and `Reference#inspect`.
#
# `::p` and `::p!` use this method to print an object in `STDOUT`.
…9974) Co-authored-by: Beta Ziliani <beta@manas.tech>
This patch changes the method definitions as proposed in #9966 and adds some additional notes.
The part about ambigouity of collection members is removed because that's not generically relevant for
#inspect
but for individual implementations such asArray#inspect
. So I added a short note about it there.It does not need to be repeated for every collection type.
Resolves #9966