2016-10-21 41 views
1

似乎RubyMine IDE在發現負面條件語句時發出警告。我想知道爲什麼使用負面條件語句是不好的?這純粹是由於可讀性?Ruby中的否定條件語句

例如,在這個代碼:

class Complement 
    def self.of_dna dna_strand 
     dna_array = dna_strand.chars 
     dna_complement = [''] 
     dna_structure = ['C', 'G', 'T', 'A'] 

     dna_array.each do |strand| 
     unless dna_structure.include? strand 
      return '' 
     end 

     case strand 
     when "C" 
     dna_complement << "G" 
     when "G" 
     dna_complement << "C" 
     when "T" 
     dna_complement << "A" 
     when "A" 
     dna_complement << "U" 
     end 
     end 
    dna_complement.join('') 
    end 
end 

我想知道在這種情況下unless dna_structure.include? strandif !(dna_strucutre.include?)之間有什麼不同?

+0

你可以寫你的'case'聲明'dna_complement <<情況下的鏈;當「C」然後「G」時;當「G」然後「C」時;當「T」接着「A」時;當「A」然後「U」時; end'。或者,您可以編寫'dna_complement << strand.tr(「CGTA」,「GCAU」)'。 –

回答

5

由於紅寶石已不僅僅是if,但unless,我們鼓勵你這麼長時間使用它作爲生成的代碼清楚了。這是你應該是這樣的轉換:

if (!string.empty?) 
    # ... 
end 

弄成這個樣子:

if (!string.empty?) 
    # ... when not empty 
else 
    # ... when empty (when not not empty) 
end 

簡易方法將:

unless (string.empty?) 
    # ... 
end 

有例外,當你有這個喜歡應該將其轉換爲unless,但會產生三重否定。你已經在這裏處理了一個雙倍,else子句只發生如果字符串是不是空,或可以說不包含任何東西

而是執行此操作:

if (string.empty?) 
    # ... when empty 
else 
    # ... when not empty 
end 

有許多與你在這裏採用的方法問題,但最嚴重的是,你每一次的方法是宣佈你的方法內部常量數組調用。由於這一點永遠不會改變,因此它在班級的頂部是一個常數。至少有:

class Complement 
    DNA_STRUCTURE = %w[ C G A T ] 
end 

更妙的是使用一個映射表來表示配對:

COMPLEMENT = { 
    'C' => 'G', 
    'G' => 'C', 
    'T' => 'A', 
    'A' => 'U' 
}.freeze 

現在看看您的特定問題,其中你想「反轉」的定鏈字符,你真正想要的工具是tr在字符串本身,這是處理之類的東西cyphers那裏有一個1優化的方法:字符之間的一對一映射。如果你想要做一個快速的測試,以確保您實際處理有效序列

def self.of_dna(strand) 
    strand.tr('CGTA', 'GCAU') 
end 

現在:

你的整個功能崩潰這一

def self.of_dna(strand) 
    return '' unless (strand.match(/\A[CGTA]*\z/)) 

    strand.tr('CGTA', 'GCAU') 
end 

還有一些其他的不良你在這裏得到的習慣,比如創建數組來保存單個字符,當字符串在這個特定的任務上更好。 c = ''然後c << 'G'將比的相同的陣列版本更有效,尤其是考慮到陣列將保存N個串,其中每一個承載一些開銷,並且需要創建另一個串在使用join結束。在使用Ruby時,儘量減少執行計算所需的對象數量(臨時或其他),儘量減少。它通常更快,少「垃圾」。

+0

你的反應是doubleplusgood用於顯示的case語句的替代品! –

+1

@tadman哇,非常感謝。您不僅回答了我的問題,還提供了很多寶貴的建議。我現在會重構我的代碼。 –

+0

@tadman你能不能也請解釋正則表達式給我嗎?我不明白'\ A'和'\ z'在正則表達式的開始和結尾是什麼意思。 –

1

沒有錯,後一種形式,但考慮在紅寶石我們有unless我們應該使用它,當我們只有一個分支,這是最好的,在這種情況下。

無論如何,這是完全一樣的。

0

我認爲這是課程的馬...我曾與非常好的開發人員,其第一語言不是英語,他們發現If !(如果不是)更容易理解。

但是Ruby的風格指南https://github.com/bbatsov/ruby-style-guide特別喜歡unlessif !但在unless皺眉正在與else使用。

最後,它是更好地重寫爲單線尾隨條件...

return '' unless dna_structure.include? strand