Reputation: 168269
It is easy to have a condition at the head of a chain and share the rest:
if condition
get_this
else
get_that
end
.foo.bar.baz
But often, I want a condition in the middle or at the tail of a chain. The best I can think of is using instance_eval
:
foo.bar
.instance_eval{
if condition
get_this
else
get_that
end
}
.baz
But I have concern that calling instance_eval
is heavy, so I actually end up not doing it. Is it worth doing so? Is there a better way, or should I just simply write:
if condition
foo.bar.get_this
else
foo.bar.get_that
end
.baz
Upvotes: 3
Views: 156
Reputation: 2625
Why not provide a method on bar
which accepts a boolean value and then acts accordingly? This encapsulates the logic and can even shield complex logic or multiple conditions, without getting too messy.
class Bar
def get_what(condition)
case condition
when qux; get_this(param1)
when quux; get_that(param1, param2)
else get_other(param1)
end
end
end
# assuming `bar` is an instance of `Bar`
foo.bar.get_what(cond).baz
PS: Depending on the use case I often try to avoid stuff like overly long message chains (because according to the Law of Demeter (Wikipedia) this might be considered bad practice :)), though when working with hashes and arrays in ruby it's kind of useful. So I suppose you have a valid use case for using a long message chain.
Upvotes: 3
Reputation: 26164
Sometimes a low-tech solution is the best:
my_bar = foo.bar
if condition
my_thing = my_bar.get_this
else
my_thing = my_bar.get_that
end
my_thing.baz
Seriously, I consider it far more important that the meaning of source code is 100% clear to everybody (including yourself some time in the future) than it being shortened by a line or two.
Upvotes: 2
Reputation: 23770
How about using Object#send to conditionally call a method:
foo.bar.send(condition? ? :get_this : :get_that).baz
In a more complicated case, with multiple/different parameters one could use the splat operator to unwrap an array into parameters:
foo.bar.send(
* case conditional
when qux
[:get_this, param1]
when quux
[:get_that, param1, param2]
else
[:get_other, param1, param2]
end
).baz
Upvotes: 3