2013-04-08 96 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 

我真的很感激您的想法,隨時發表評論!