From: "ko1 (Koichi Sasada) via ruby-core" Date: 2024-12-04T02:56:28+00:00 Subject: [ruby-core:120095] [Ruby master Feature#14609] Let `Kernel#p` without an argument print the receiver Issue #14609 has been updated by ko1 (Koichi Sasada). Status changed from Assigned to Rejected out of date ---------------------------------------- Feature #14609: Let `Kernel#p` without an argument print the receiver https://bugs.ruby-lang.org/issues/14609#change-110842 * Author: ko1 (Koichi Sasada) * Status: Rejected * Assignee: matz (Yukihiro Matsumoto) ---------------------------------------- # 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 || '' } .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 || '' }.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 || '' }.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. -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/