Feature #12760
closedOptional block argument for `itself`
Description
That's an another attempt to choose good metaphor for object.(yield self)
(previously: #6721 and ton of duplicates).
In discussion here: https://bugs.ruby-lang.org/issues/11717#note-3 it was said:
Clearly this is something the Ruby community wants. Just as clearly, it's something nobody can name.
But suddenly... I've thought about this!
some.long.method.chain.constructing.string
.itself { |s| "(" + s + ")" }
.itself(&method(:puts))
# or
require 'open-uri'
construct_url(*params)
.itself(&method(:open))
.read
.itself(&JSON.method(:parse))
.to_yaml
.itself(&File.method(:write))
# NB: I understand that _last_ `itself` in both examples
# could as well be `tap`. But not all the previous.
Pros:
- method is already here, it has pretty name and underused (almost nothing except
group_by(&:itself)
comes to mind); - it is not 100% good English, but readable:
itself(&JSON.method(:parse))
= "parse itself with json"; - implementation is trivial, no backwards-compatibility issues (like new methods shadowing something important in third-party library) are expected.
Cons:
- ???
Updated by phluid61 (Matthew Kerwin) about 8 years ago
Updated by zverok (Victor Shepelev) about 8 years ago
OK, I did not my homework really well this time.
But, to be completely honest, I'm fascinated by how this simple, easy to implement and useful functionality have drowned for ages in "better-name-ever" discussions.
Updated by shevegen (Robert A. Heiler) about 8 years ago
But, to be completely honest, I'm fascinated by how this simple, easy to
implement and useful functionality have drowned for ages in "better-name-ever"
discussions.
This is not surprising at all because naming things is one of the hardest
things to get "right".
You just have to look at various rubygems that have a very strange name.
Animal names for instance - a webserver called puma? unicorn as a HTTP server
for Rack applications?
I can give you another example too, look at some years ago the "File.exist?"
versus "File.exists?" when both was made available as alias after some people
spoke to matz. I personally don't care much either way since I understand
both points. In "correct" pseudo-english grammar, we can say "does this
file exist?" and "file exists?", but I remember an explanation by apeiros
on IRC once that this would not be the right question asked according to
matz. The question would instead be "object, do you exist?" or "object,
do you contain xyz?". It may be a subtle and minor difference but it sort
of also taps into the philosophy of ruby.
People need or should be vaguely comfortable with syntax. Take the lambda
stabby operator, I can not overcome my mental obstacle to use it - it just
does not "feel right" in my own code. Lots of other people make use of it,
that is fine by me.
Back to the topic of .itself, while I have no strong objection, I struggle
with other method names such as .tap - whenever I read .tap, I actually
think of a certain card game where you have to tap cards. :)
.inject is another odd one, I think of a big nasty syringe (actually my
brain associates it more as name like "sum of", because that is what I
use .inject most regularly like "array.inject(0){|sum,x| sum + x }"
although I suppose there may be another way these days to get the sum
of all integer/float products of an array).
In conclusion, I think you have to expect a certain resistance in particular
for syntax. Best thing is to try to convince matz. And if it won't
work within ruby 2.x and neither towards the path towards ruby 3.x
and beyond, perhaps it works for ruby 4.x :)
(Actually, perhaps the DSL aspect of ruby could be extended one day
to allow sub-languages of ruby a bit like lisp dialects... but let's
not get too crazy here.)
Updated by zverok (Victor Shepelev) about 8 years ago
But, to be completely honest, I'm fascinated by how this simple, easy to
implement and useful functionality have drowned for ages in "better-name-ever"
discussions.
This is not surprising at all because naming things is one of the hardest
things to get "right".
I can understand your point, but sometimes struggle for excellence should just stop to do the real work.
Concept of .yield_self
(or whatever we name it) method seems like a huge game-changer to me in a challenge of cleaner and idiomatic code. Yes, it's like Elixir's |>
operator, but it could be introduced in no effort at all.
Does nobody can see it?
I don't think so, considering how often the question is raised. Four 4 years now (and it is only proposals that are found in tracker)!
OK, let's summarize EVERYTHING that was proposed (and doubted) so far:
- #6721:
-
#yield_self
, -
#yield_to
, -
#submit_to
, -
#surrender
, -
#capitulate
, -
#apply
, -
#ergo
(implemented in Ruby Facets exactly like#itself
proposed here); -
#^
(likefour = 2 ^ { |x| x*x }
) -
#self
(again, like#itself
-- yield-or-return-self) -
#cast
(more complicated behavior, like3.cast(2, :+) => 5
) #toss
#tap!
-
- #7388 (Matz had explicitly stated he is against all of the options)
#embed
#infix
-
#ergo
again
- #6684 (proposal & discussion is partially in Japanese)
#do
- #11717
-
#trap
(was my idea, I've liked it to be close to#tap
yet was pointed to confusion withSignal#trap
)
-
- #10095
#as
#chain
#self_by
#revapply
#block_self
-
#itself
(and big discussion why it is not appropriate -- don't really persuadive for me, but you can know batter) #yield
- block form of
#send
(like(2 + 3).send{ |x| x + 2 }
) - new method/operator
~>
- Using just
|
operator #continue
My favourite is, obviously, itself
, "reading" reasoning could be found above:
it is not 100% good English, but readable:
itself(&JSON.method(:parse)) = "parse itself with json"
;
But, to be honest, it is not the point. Point is we need it, whatever it is called. And except for "new operator" approach, and versions that will confuse parser (self
, yield
and do
), it is really easy to implement after the name was selected.
Please-please-please, could somebody add this topic to next developer's meeting agenda?..
Updated by duerst (Martin Dürst) about 8 years ago
Victor Shepelev wrote:
Please-please-please, could somebody add this topic to next developer's meeting agenda?..
Done, please see https://bugs.ruby-lang.org/projects/ruby/wiki/DevelopersMeeting20161011Japan.
Updated by zverok (Victor Shepelev) about 8 years ago
Thanks a lot! (But, sorry for bothering, could it be discussed as "Optional block argument for itself OR another name for yield self
method"? Like, in hope for final solution, not "optional block argument for itself is rejected, and that's it". List of proposed names I've gathered in current ticket.)
Updated by nobu (Nobuyoshi Nakada) about 8 years ago
- Is duplicate of Feature #6721: Object#yield_self added
Updated by nobu (Nobuyoshi Nakada) about 8 years ago
- Is duplicate of Feature #6684: Object#do added
Updated by nobu (Nobuyoshi Nakada) about 8 years ago
- Is duplicate of Feature #7388: Object#embed added
Updated by nobu (Nobuyoshi Nakada) about 8 years ago
- Is duplicate of Feature #10095: Object#as added
Updated by nobu (Nobuyoshi Nakada) about 8 years ago
- Is duplicate of Feature #11717: Object#trap -- pass object to block and return result added
Updated by nobu (Nobuyoshi Nakada) about 8 years ago
What about let
?:
some.long.method.chain.constructing.string
.let { |s| "(" + s + ")" }
Updated by shyouhei (Shyouhei Urabe) about 8 years ago
FYI we looked at this issue at developer meeting today. Because matz was not there this extension still has chance, but the attendees thought itself
's block (if any) shall work like how tap
works. So it might not be suitable for the requested functionality.
Updated by zverok (Victor Shepelev) about 8 years ago
Thanks for the update! Haven't you discussed the probable another name for it?.. We just want it to be in language already.
Updated by knu (Akinori MUSHA) about 8 years ago
What about giving it an obvious name like yield_self
and making a syntax sugar object.{|x| ... }
for calling it like we do in Proc#call?
Updated by matz (Yukihiro Matsumoto) almost 8 years ago
yield_self
is OK, but I don't think we are going to add object.{|x| ... }
.
Matz.
Updated by zverok (Victor Shepelev) almost 8 years ago
Well, I should say yield_self
is not very readable in context (it raises question which is "self" in that context?):
construct_url(*params)
.yield_self(&method(:open))
.read
.yield_self(&JSON.method(:parse))
.to_yaml
.yield_self {|yml| File.write('cache.yml', yml) }
But I'd rather prefer to finally have this method in core language, whatever it will be named :)
Updated by nobu (Nobuyoshi Nakada) almost 8 years ago
- Has duplicate Feature #13172: Method that yields object to block and returns result added
Updated by Nondv (Dmitry Non) almost 8 years ago
Hello.
Is there any movement?
Updated by ko1 (Koichi Sasada) over 7 years ago
how about alter
?
at dev meeting, someone said reform
.
Updated by zverok (Victor Shepelev) over 7 years ago
I believe the situation should be addressed just by somebody's authority.
What do you think about appointing the name selection for next core dev meeting? You can just take a list that gathered in current ticket and do some voting or something.
I don't think it is an acceptable situation when really useful method is not introduced for 4 years since first proposal (if it haven't proposed before, which I am not sure) just because nobody wants to choose the name.
TBH, for me open('http://some.url').read.itself(&JSON.method(:parse))
still looks like a cleanest solution possible, yet I'd just prefer to see this method in core, with whatever name.
If Matz is OK with yield_self
, let it be yield_self
.
Updated by nobu (Nobuyoshi Nakada) over 7 years ago
- Status changed from Open to Closed
Applied in changeset trunk|r58528.
object.c: Kernel#yield_self
- object.c (rb_obj_yield_self): new method which yields the
receiver and returns the result.
[ruby-core:46320] [Feature #6721]
Updated by nobu (Nobuyoshi Nakada) over 7 years ago
- Has duplicate Feature #13559: Change implementation of Feature #6721 added