Is there a good way to chain methods conditionally in Ruby?
What I want to do functionally is
if a && b && c
my_object.some_method_because_of_a.some_method_because_of_b.some_method_because_of_c
elsif a && b && !c
my_object.some_method_because_of_a.some_method_because_of_b
elsif a && !b && c
my_object.some_method_because_of_a.some_method_because_of_c
etc...
So depending on a number of conditions I want to work out what methods to call in the method chain.
So far my best attempt to do this in a "good way" is to conditionally build the string of methods, and use eval
, but surely there is a better, more ruby, way?
If you're using Rails, you can use
#try
. Instead ofwrite:
or, with arguments:
Not defined in vanilla ruby, but it isn't a lot of code.
What I wouldn't give for CoffeeScript's
?.
operator.Although the inject method is perfectly valid, that kind of Enumerable use does confuse people and suffers from the limitation of not being able to pass arbitrary parameters.
A pattern like this may be better for this application:
I've found this to be useful when using named scopes. For instance:
You can use
tap
:Here's a more functional programming way.
Use
break
in order to gettap()
to return the result. (tap is in only in rails as is mentioned in the other answer)You could put your methods into an arry and then execute everything in this array
Object#send
executes the method with the given name.Enumerable#inject
iterates over the array, while giving the block the last returned value and the current array item.If you want your method to take arguments you could also do it this way
Sample class to demonstrate chaining methods that return a copied instance without modifying the caller. This might be a lib required by your app.
monkeypatch: this is what you want to add to your app to enable conditional chaining
Sample usage