Project

General

Profile

Feature #14594

Rethink yield_self's name

Added by zverok (Victor Shepelev) over 2 years ago. Updated over 1 year ago.

Status:
Closed
Priority:
Normal
Target version:
-
[ruby-core:86270]

Description

I feel really uncomfortable raising the question again, but...

In several months since 2.5 release I've written a lot of code with yield_self (using backports gem with earlier versions of Ruby when necessary), and explained it several times to students, and colleagues (and in this blog post which have gained pretty decent attention).

I should say that I am still assured the name chosen is really not optimal. Reasons:

  • it is just too long for such a basic operation;
  • it does not say "what it does", but rather "how it is implemented"; it is like having each_returning_block_result instead of map;
  • self is really misguiding and obscure in situations like this:
class MyClass
  def some_method
    @path.yield_self(&File.method(:read)).yield_self(&Parser.method(:new)) ...
  end
end

Intuitively, word "self" inside instance method is read like it somehow related to current context's self (e.g. instance of MyClass), which it is absolutely not. In other words, "self" in caller's context has nothing to do with "self" implied by method's name.

After reconsidering a lot of options, my current proposal is: #then.

Reasons:

  • despite being a keyword, something.then(something) is not a conflicting Ruby syntax, and allowed by current Ruby;
  • it is short!
  • it shows intention pretty well, and reads natural, in both cases: when receives block and when returns Enumerator:
File.read(filename).then(&JSON.method(:parse))
rand(10).then.detect(&:odd?)

In many languages, .then or .and_then is useful construct, meaning the same (calculate next value from the result of the previous operation), just in a narrower context of futures/promises. I believe that even when/if Ruby will have those as a language feature, that syntax will play well:

value.then(&:computation) # => value
promise.then(&:computation) # => promise

PS: For historical reasons, here is huge list of previous proposals I've gathered for this method name.

Also available in: Atom PDF