
Issue #21435 has been updated by zverok (Victor Shepelev). @Alexander.Senko I don't think my opinion weights much here, but here it is, nevertheless. When writing in "chaining" style (which I know is not everybody's favorite), "do this transformation/next step conditionally" is indeed a frequent thing that comes to mind. There are two cases: a) the condition depends on the `self` (the current step of the chain) and b) the condition doesn't depend on it. For the latter, I would've liked (though I don't feel strongly enough to propose it) something like `then_if`: ```ruby def save(data, path, compress: true) data .do_something .do_something_else .to_json .then_if(compress) { Compression.call(it) } # skipped just returning self if condition is false .then { File.write(path, it) } end ``` For a case when the step depends on `self` in that step, I don't have an idea of a good syntax, TBH. Maybe something like this (though purely theoretical, I wouldn't really want to add more lambdas to the code this way, both for "too much punctuation" and performance concerns): ```ruby data .do_something .do_something_else .to_json .then_if(-> { it.size > LIMIT }) { Compression.call(it) } .then { File.write(path, it) } ``` I understand where the idea of `optional` is coming from, but for me, both the name and the usage seem kinda ambiguous. In any case, I rarely miss this option that much, and never had a good idea of a "proper" syntax/API to allow that. ---------------------------------------- Feature #21435: Kernel#optional as a conditional #then https://bugs.ruby-lang.org/issues/21435#change-113759 * Author: Alexander.Senko (Alexander Senko) * Status: Open ---------------------------------------- ## What When chaining, I need sometimes to apply some changes conditionally, like this: ```ruby @record = Record.find(record_id) .then { it.respond_to?(:decorate) ? it.decorate : it } ``` It would be great to DRY it a bit: ```ruby @record = Record.find(record_id) .optional { it.decorate if it.respond_to? :decorate } ``` Or, even shorter for Rails users: ```ruby @record = Record.find(record_id) .optional { it.try :decorate } ``` ## Why The intent is to **make it visible at a glance that a statement _may_ affect the result**, but not necessarily does so. Without the proposed method, one needs to read and parse the whole block to know that. It should help to read longer processing chains, for those who prefer chains and `#then` to plain old iterative approach. ## Naming It is discussible. I have just two ideas yet: - `optional` - `maybe` ## Reference implementation ```ruby # Yields self to the block and returns the result of the block if it’s # truthy, and self otherwise. def optional tap do result = yield(self) or next break result end end ``` -- https://bugs.ruby-lang.org/