Project

General

Profile

Feature #15557

A new class that stores a condition and the previous receiver

Added by sawa (Tsuyoshi Sawada) over 1 year ago. Updated over 1 year ago.

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

Description

I often see code like this:

foo = default_definition
foo = some_method(foo) if some_condition(foo)
foo = another_method(foo) if another_condition(foo)
...

It would be nice if we can write this as a method chain. Since we now have the method then, I thought it would be a nice fit to introduce a method called when, such that putting it right in front of then would execute the then method as ordinarily only when the condition is satisfied, and returns the previous receiver otherwise so that the code above can be rewritten as:

foo =
default_definition
.when{|foo| some_condition(foo)}
.then{|foo| some_method(foo)}
.when{|foo| another_condition(foo)}
.then{|foo| another_method(foo)}

This proposal is also a generalization of what I intended to cover by https://bugs.ruby-lang.org/issues/13807. That is,

a.some_condition ? a : b

would rewritten as:

a.when(&:some_condition).then{b}

The proposal can be implemented by introducing a class called Condition, which stores a condition and the previous receiver, and works with then in a particular way.

class Object
  def when
    Condition.new(self, yield(self))
  end
end

class Condition
  def initialize default, condition
    @default, @condition = default, condition
  end

  def then
    @condition ? yield(@default) : @default
  end
end

And additionally, if we introduce a negated method unless (or else) as follows:

class Object
  def unless
    Condition.new(self, !yield(self))
  end
end

then we can use that for purposes such as validation of a variable as follows:

bar =
gets
.unless{|bar| some_validation(bar)}
.then{raise "The input is bad."}
.unless{|bar| another_validation(bar)}
.then{raise "The input is bad in another way."}

Related issues

Related to Ruby master - Feature #13807: A method to filter the receiver against some conditionClosedActions

Also available in: Atom PDF