Project

General

Profile

Feature #14625

yield_self accepts an argument, calling to_proc

Added by irohiroki (Hiroki Yoshioka) 10 months ago. Updated 10 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

Updated by zverok (Victor Shepelev) 10 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)

Updated by shevegen (Robert A. Heiler) 10 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).

Updated by irohiroki (Hiroki Yoshioka) 10 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.

Updated by irohiroki (Hiroki Yoshioka) 10 months ago

shevegen,

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

Also available in: Atom PDF