Normally I love sawa's suggestions. :)
However had, in this case, I am a little bit biased, which I may explain.
First, I should start here by agreeing with sawa in regards to the use case noted on top is quite common -
I use it myself a lot, but I see it in other people's ruby code as well:
foo = default_definition
foo = some_method(foo) if some_condition(foo)
foo = another_method(foo) if another_condition(foo)
Or perhaps in a simpler variant, more often this:
foo = default_definition
foo = some_method(foo) if some_condition
foo = another_method(foo) if another_condition
These can be method calls too:
foo = new_colour if use_colours?
I think the latter can be quite common if people wish to determine
what users may want to use; e. g. from a commandline interface,
like if you start a project with commandline flags --disable-colours
or any other flag. So yes, I think this can be quite common.
sawa gave an alternative proposal:
.when{|foo| some_condition(foo)}
.then{|foo| some_method(foo)}
.when{|foo| another_condition(foo)}
.then{|foo| another_method(foo)}
Now I should say that I personally actually prefer the "oldschool" variant
since, to me personally, the intent is more clear. Another minor concern I
have is that .when and .then are not so easy to distinguish visually; when
is also used in case/when menu interfaces, which I love (so I am not that
enthusiastic about using more "when" in other places in ruby, to be
honest).
Which variant to prefer is of course heavily up to the individual person
at hand but in my opinion I think using mixed .when and .then is not as
easy or straightforward than the other variant.
Nobu suggested:
.when(->(foo) {some_condition(foo)}) {|foo| some_method(foo)}
Here I can not comment much on it since I feel that in my own projects
the "->" always felt odd. Combining it with .when would make the code
even more odd (to me). Obviously the milage of other people may differ
here, so this is again a personal preference.
Aside from syntactic considerations, I also feel that the variant with
.when(->(foo) {another_condition(foo)}) {|foo| another_method(foo)} is
harder to break up in the head than the oldschool if/else variant checks.
sawa also suggested:
a.some_condition ? a : b
would rewritten as:
a.when(&:some_condition).then{b}
which I think is not ideal either, because it is longer. I myself avoid the ternary
operator, though, because it always takes my brain a little longer than e. g.
just an if; and a return (if we can avoid using an else altogether, or even better,
to simply use a conditional method call such as one that uses a boolean
return, if we can avoid if/else branching altogether, which can lead to even
simpler code layouts). But this is again up to one's personal preference, and
since I am biased I am admittedly not trying to find good alternative point of
views. :)
Do note that I am not at all against sawa's suggestion or statement that "would be nice if
we can write this as a method chain". I think that part is fine; avoiding if/else branches
can be good in some cases. I am just somewhat concerned in regards to the syntax-verbosity
and that it may lead to more complicated code - the intent in the proposal otherwise is
perfectly fine. This is of course just my personal opinion. :)
zverok just wrote this as I was about to finish my comment ... :P
for the sake of nice syntax, e.g. something.if(&:cond?) on itself doesn't produce an
easily explainable/reusable object.
Here we have to ask whether the alternative syntax proposals are better or really
are a "nice syntax". I have my doubts. :)
Also note that:
something.if
something.else
something.if(&:cond?)
something.else(&:cond?)
I consider actually significantly worse syntax. :D