Project

General

Profile

Actions

Feature #14609

open

Let `Kernel#p` without an argument print the receiver

Added by ko1 (Koichi Sasada) over 6 years ago. Updated 8 months ago.

Status:
Assigned
Target version:
-
[ruby-core:86152]

Description

Abstract

Kernel#p(obj) prints obj as inspected.
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".

[ruby-dev:30903]

  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.


Related issues 2 (2 open0 closed)

Related to Ruby master - Feature #15112: Introducing the short form of `STDERR.puts expr.inspect`.Assignedmatz (Yukihiro Matsumoto)Actions
Related to Ruby master - Feature #18736: self-p for method chainOpenActions
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0