How to write a difficult condition

Condition constructs are easy to write when you have a simple condition and possibly a complex body:

if simple_condition_expressed_in_one_liner complicated_body_that_may_be_long complicated_body_that_may_be_long complicated_body_that_may_be_long end 

but sometimes you have a difficult condition and a simple body like this:

 if condition1 and condition2 and condition3 and some_more_complicated_condition_that_cannot_be_written_on_a_single_line and still_some_more_complicated_condition_that_cannot_be_written_on_a_single_line simple_body end 

In that case, is there a good way to write it?

+4
source share
4 answers

I always try to reorganize into smaller descriptive methods.

Using your example, instead of:

 until (print "Username : "; gets.chomp == "user") and (print "Password : "; gets.chomp == "pa$$word") puts "Error, incorrect details" end 

I would use:

 def correct_user print "Username : " gets.chomp == "user" end def correct_password print "Password : " gets.chomp == "pa$$word" end until correct_user and correct_password puts "Error, incorrect details" end 
+5
source

I personally passed the entire conditional statement to a separate method. This may sound very similar to what has already been suggested, but I put all this into the method instead of breaking it.

 simple_body if complicated_condition def complicated_condition condition1 and condition2 and condition3 and some_more_complicated_condition_that_cannot_be_written_on_a_single_line and still_some_more_complicated_condition_that_cannot_be_written_on_a_single_line end 

I can or cannot break down the condition into more methods depending on the conditions and whether I will use these methods later (too many methods used for one purpose only begin to become code smells).

This makes the code readable (I can hide the code and see what it does) and supports it (I can change the condition if necessary, and I know exactly where it is).

If I put this in a class, I would put the method under private , since there is no reason why the "external" should use it.

EDIT: If conditions require variable values ​​during use in a condition, perhaps consider switching to the binding method.

 opt = :mysql simple_body if complicated_condition(binding) opt = :oracle simple_body if complicated_condition(binding) def complicated_condition(b) condition1 and condition2 and condition3 and some_more_complicated_condition_that_cannot_be_written_on_a_single_line and still_some_more_complicated_condition_that_cannot_be_written_on_a_single_line and eval('opt', b) == :mysql end 
+2
source

You should consider splitting into separate methods. It is difficult to mentally display the conditions when reading the code:

 if(condition1 and condition2 and ...) 

vs

 if(isValidCondition()).. 
+1
source

Early returns may be a candidate when calling the complex_condition method.

 simple_body if complex_condition def complex_condition condition1 or return # or return unless condition1 condition2 or return condition3 or return condition4 or return condition5 end def condition4 some_more_complicated_condition_that_cannot_be_written_on_a_single_line end def condition5 still_some_more_complicated_condition_that_cannot_be_written_on_a_single_line end 

I really appreciate your thoughts, do not hesitate to comment!

0
source

All Articles