Issue #14609 has been updated by docx (Lukas Dolezal).


Allowing debugging within `yield_self` is great! If `yield_self` was inspired by Elixir, we can look at Elixir for inspiration here as well:

https://hexdocs.pm/elixir/IO.html#inspect/2

One of the examples that is very interesting is that they have optional parameter to describe the printout:

```
[1, 2, 3]
|> IO.inspect(label: "before")
|> Enum.map(&(&1 * 2))
|> IO.inspect(label: "after")
|> Enum.sum
```

Prints:

```
before: [1, 2, 3]
after: [2, 4, 6]
```

I'm wondering, would that be something we would like in Ruby too?

The problem with the proposal of making `obj.p` is that the same method already is defined with parameter in the form of `p(obj)`.

Hence it would be impossible to implement `obj.p("after")` - as that would conflict with the current version of `p` with parameter.

My feeling is that given that both `yield_self` and `tap` are defined on `Object`, it does not feel to me right that `.p` should be defined on `Kernel`. I can see the advantage of already existing method there, but I feel like it would be wrong overloading.

Continuing on the argument that `yield_self` is defined on `Object`, should we define this "print inspect and return self" method be defined on `Object too`?

If so, we can keep the name `Object.p` and implement it with new interface when called as instance method and avoid making `Kernel.p` public:

```
Object.p() - p self.inspect and return self
Object.p(label:) - p "#{label}: #{self.inspect}" and return self
```

What do you think?

----------------------------------------
Feature #14609: `Kernel#p` without args shows the receiver
https://bugs.ruby-lang.org/issues/14609#change-74439

* Author: ko1 (Koichi Sasada)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version: 2.6
----------------------------------------
# Abstract

`Kernel#p(obj)` prints obj as `inspect`ed.
How about to show the receiver if an argument is not given?

# Background

We recently introduce `yield_self` which encourages block chain.

https://zverok.github.io/blog/2018-01-24-yield_self.html
Quoted 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 at debugging.
If we want to see the middle values in method/block chain, we need to insert `tap{|e| p e}`.

With 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

`obj.p` shows same as `p(obj)`.

We can replace
  `block{...}.tap{|e| p e}`
to 
  `block{...}.p`

For above example, we can simply add `.p` at the end of 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 issue

(1) Shorthand for `nil`

This spec change can introduce compatibility issue because `p` returns `nil` and do not output anything.
That is to say, `p` is shorthand of `nil`. Some code-golfers use it.

Maybe we can ignore them :p

(2) make public method

`Kernel#p` is private method, so if we typo `obj.x` to `obj.p` (not sure how it is feasible), it will be `NoMethodError` because of visibility.
We need to change this behavior.

# Note

## Past proposal and discussion

Endoh-san proposed same idea 10+ years ago [ruby-dev:29736] in Japanese.
I think we should revisit this idea because of `yield_self` introduction.

At 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 the behavior of (I feel strange that it is similar to `p(self)`):

  p

What happen on

  self.p(obj)
```

## pp

If this proposal is accepted, we also need to change `pp` behavior.

## gems

`tapp` method is provided by gem.
https://github.com/esminc/tapp 

I'd thought to propose this method into core. But I found that `p` is more shorter than `tapp`.
Disadvantage is `p` is too short and difficult to grep.




-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>