Condition constructions are easy to write when you have a simple condition and a possibly complicated 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 complicated 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 such case, is there a good way to write it?
I always try to refactor 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
I personally put the entire conditional statement into a separate method. This may sound a lot like what has been suggested already but I put the entire thing into a method instead of breaking it up.
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 may or may not break up the condition into more methods depending on what the conditions are and whether I will end up using those methods later (too many methods used for only one purpose starts to become code smell).
It makes the code readable (I can skim the code and see what it is doing) and maintainable (I can alter the condition if need be and I know exactly where it is).
If I put this into a class, I would put the method under private
since there's no reason the 'outside' needs to use it.
EDIT:
If the conditions require the values of the variables at the time it is used in a condition, perhaps consider passing in binding
into the 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With