2013-04-08 73 views
4

条件结构很容易写,当你有一个简单的条件和可能的复杂体:如何写一个复杂的条件

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 

但有时,你有一个复杂的条件和简单的身体是这样的:

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 

在这种情况下,有没有写好它的好方法?

+0

您能向我们展示some_more_complicated_condition_that_cannot_be_written_on_a_single_line示例吗? – 2013-04-08 15:55:01

+0

请参阅我的[这个问题]答案的第一部分(http://stackoverflow.com/questions/15883056/i-need-help-in-ruby/15883285#15883285)。 – sawa 2013-04-08 15:59:16

+0

为什么不把你的一次性逻辑折成lambda? – 2013-04-08 17:03:20

回答

1

您应该考虑将其分为不同的方法。 很困难,而读码精神上映射条件:

if(condition1 and condition2 and ...) 

与:

if(isValidCondition()).. 
+1

具有代表性名称的方法 – User 2013-04-08 15:59:58

5

我总是试图重构为更小的描述性方法。

使用你的榜样,而不是:

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

我会用:

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 
2

我亲自把整个条件语句到一个单独的方法。这可能听起来很像已经建议的,但我把整个事情放到一个方法中,而不是分解它。

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 

我可能会或可能不会分手的条件为更多的方法取决于条件是什么,我是否会结束后使用这些方法(用于目的只有一个方法太多开始变得代码味道) 。它使得代码可读(我可以浏览代码,看看它在做什么)和可维护的(我可以改变条件,如果需要的话,我确切地知道它在哪里)。

如果我把这个放到一个类中,我会把这个方法放在private之下,因为'外部'不需要使用它。

编辑: 如果条件需要在它是在一个状态下使用时的变量的值,也许考虑通过在binding入方法。使得complex_condition一个方法调用时

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 
0

Early returns可能成为候选人。

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 

我真的很感激您的想法,随时发表评论!