Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

conditional chaining in ruby

Tags:

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?

like image 508
DanSingerman Avatar asked Nov 25 '09 14:11

DanSingerman


People also ask

Can you chain methods in Ruby?

Method chaining is a convenient way to build up complex queries, which are then lazily executed when needed. Within the chain, a single object is updated and passed from one method to the next, until it's finally transformed into its output value.

What is ||= in Ruby?

||= is called a conditional assignment operator. It basically works as = but with the exception that if a variable has already been assigned it will do nothing. First example: x ||= 10. Second example: x = 20 x ||= 10. In the first example x is now equal to 10.


1 Answers

You could put your methods into an arry and then execute everything in this array

l= [] l << :method_a if a l << :method_b if b l << :method_c if c  l.inject(object) { |obj, method| obj.send(method) } 

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

l= [] l << [:method_a, arg_a1, arg_a2] if a l << [:method_b, arg_b1] if b l << [:method_c, arg_c1, arg_c2, arg_c3] if c  l.inject(object) { |obj, method_and_args| obj.send(*method_and_args) } 
like image 142
johannes Avatar answered Oct 13 '22 12:10

johannes