Project

General

Profile

Feature #14625

yield_self accepts an argument, calling to_proc

Added by irohiroki (Hiroki Yoshioka) 4 months ago. Updated 4 months ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:86260]

Description

Currently, yield_self doesn't accept any argument other than a block.

But there are situations where I would like to pass a method object to yield_self.
e.g.

result = collection
  .yield_self(&method(:filter1))
  .yield_self(&method(:filter2))

Of course, we can get the same result with

result = filter2(filter1(collection))

but the order of reading/writing doesn't match the order of thinking.

My request is for yield_self to accept a proc-ish object and call to_proc on it so that we can write the code as shown below, which is more readable.

result = collection
  .yield_self(method :filter1)
  .yield_self(method :filter2)

History

#1 [ruby-core:86261] Updated by zverok (Victor Shepelev) 4 months ago

Question 1. How is this (proposed):

result = collection
  .yield_self(method :filter1)
  .yield_self(method :filter2)

better than this (already works):

result = collection
  .yield_self(&method(:filter1))
  .yield_self(&method(:filter2))

?

Question 2: what about all other methods that accepts blocks of code? If the syntax shown above is available for #yield_self, shouldn't it become available for #each, #map and everything else?..

collection.yield_self(method :filter1)
collection.map(method :filter1)

I believe that the real improvement of "passing the method" situation would be the #13581, so you can write something like:

collection
  .yield_self(&.:filter1)
  .yield_self(&.:filter2)

#2 [ruby-core:86267] Updated by shevegen (Robert A. Heiler) 4 months ago

I can't answer all questions zverok posed but in regards to:

.yield_self(method :filter2)

versus

.yield_self(&method(:filter1))

The first variant is cleaner IMO.

As for (&.:filter1) I don't really like that suggestion and
I think it should not be connected to irohiroki's issue
request here since he did not suggest it. :)

While I agree that it would be great if we could have a
way to also pass in arguments rather than just invoke
method calls vie e. g. array.map(&:strip) alone, I am
not convinced that &.: should be the way to go. It
looks very perlish and the dots are not so easily
distinguishable (we use :: for "namespace" separators
currently and . for method calls).

So on that, I think we should keep towards the suggestion
itself given by irohiroki. And I think he meant it only
for yield_self, not for any other method. Of course one
can argue that symmetry should exist for all methods
(though I am not sure as to why, other than thinking
that symmetry is more important even if it may be useless
for some methods).

#3 [ruby-core:86402] Updated by irohiroki (Hiroki Yoshioka) 4 months ago

zverok,

Answer 1.

.yield_self(method :filter1)

is shorter than

.yield_self(&method(:filter1))

and doesn't have nested parens.

Answer 2: I don't really know about other methods, but there is a method named Enumerable#inject and actually it accepts a symbol as an argument that is special among methods having a block. What I mean is that there can be a special method, although I'm not sure it's really nice.

Regarding #13581, it can help me but anyway it's still open right now.

#4 [ruby-core:86403] Updated by irohiroki (Hiroki Yoshioka) 4 months ago

shevegen,

That's what I meant to say. Thank you.

Also available in: Atom PDF