Feature #14609
openLet `Kernel#p` without an argument print the receiver
Description
Abstract¶
Kernel#p(obj)
prints obj
as inspect
ed.
How about printing the receiver if an argument is not given?
Background¶
We recently introduced yield_self
, which encourages block chain.
https://zverok.github.io/blog/2018-01-24-yield_self.html
Quoting from this article, we can write method chain with blocks:
construct_url
.yield_self { |url| Faraday.get(url) }.body
.yield_self { |response| JSON.parse(response) }
.dig('object', 'id')
.yield_self { |id| id || '<undefined>' }
.yield_self { |id| "server:#{id}" }
There is a small problem concerning debugging.
If we want to see the intermediate values in the method/block chain, we need to insert tap{|e| p e}
.
With the above example,
construct_url
.yield_self { |url| Faraday.get(url) }.body
.yield_self { |response| JSON.parse(response) }.tap{|e| p e} # debug print
.dig('object', 'id')
.yield_self { |id| id || '<undefined>' }.tap{|e| p e} # debug print
.yield_self { |id| "server:#{id}" }
Proposal¶
Let obj.p
work the same as p(obj)
.
We can replace
block{...}.tap{|e| p e}
with
block{...}.p
For the above example, we can simply add .p
at the end of a line:
construct_url
.yield_self { |url| Faraday.get(url) }.body
.yield_self { |response| JSON.parse(response) }.p # debug print
.dig('object', 'id')
.yield_self { |id| id || '<undefined>' }.p # debug print
.yield_self { |id| "server:#{id}" }
Compatibility issues¶
(1) Shorthand for nil
This spec change can introduce compatibility issues because p
returns nil
and does not output anything.
That is to say, p
is a shorthand for nil
. Some code-golfers use it.
Maybe we can ignore them :p
(2) make it a public method
Kernel#p
a is private method, so if we mistype obj.x
as obj.p
(not sure how it is feasible), it will raise a NoMethodError
because of visibility.
We need to change this behavior.
Note¶
Past proposal and discussion¶
Endoh-san proposed the same idea 10+ years ago [ruby-dev:29736] in Japanese.
I think we should revisit this idea because of yield_self
introduction.
In this thread, Matz said "simple p
shows p(self)
, it is not clear".
p
はどう動くのかとか(p selfと同じ、は変な気が)
self.p(obj)
はどうなのかとか。その辺が解決(納得)できたら、ということで。
English translation:
What would the behavior of:
p
be? (I feel strange for it to be equivalent to `p(self)`.) What would happen to
self.p(obj)
pp¶
If this proposal is accepted, we also need to change the behavior of pp
.
gems¶
tapp
method is provided by a gem.
https://github.com/esminc/tapp
I thought about proposing this method in core. But I found that p
is shorter than tapp
.
A disadvantage is that p
is too short and difficult to grep.