2010-05-20 77 views
3

在一個方法中,我使用ij作爲臨時變量,同時計算其他變量。一旦不再需要它,擺脫ij的習慣用法是什麼?我應該爲此使用塊嗎?方法內臨時變量的習慣ruby

i = positions.first 
while nucleotide_at_position(i-1) == nucleotide_at_position(i) 
    raise "Assumption violated" if i == 1 
    i -= 1 
end 
first_nucleotide_position = i 
j = positions.last 
while nucleotide_at_position(j+1) == nucleotide_at_position(j) 
    raise "Assumption violated" if j == sequence.length 
    j += 1 
end 
last_nucleotide_position = j 

背景:我想擺脫ij一旦他們不再需要,使他們不使用該方法的任何其他代碼。讓我的代碼更少出錯的機會。我不知道這個概念的名稱 - 是「封裝」嗎?我能想到的最接近的概念是(警告:鏈接到電視節目 - 不要在工作時訪問)Chekhov'sGunYouHaveOutlivedYourUsefulness

另一種替代方法是將代碼放入自己的方法中,但這可能會降低可讀性。

回答

2

Ruby(像JS)不會爲每個塊默認創建一個新的作用域(如C++等)。但是,在Ruby 1.9中,您可以嘗試:

last_nucleotide_position = nil 
proc { |;i, j| 
    i = positions.first 
    while nucleotide_at_position(i-1) == nucleotide_at_position(i) 
    raise "Assumption violated" if i == 1 
    i -= 1 
    end 
    first_nucleotide_position = i 
    j = positions.last 
    while nucleotide_at_position(j+1) == nucleotide_at_position(j) 
    raise "Assumption violated" if j == sequence.length 
    j += 1 
    end 
    last_nucleotide_position = j 
}.call() 

請參閱How to make block local variables the default in ruby 1.9?。任何變量,你要在塊之外使用,應事先定義(如last_nucleotide_position)。

FM是正確的,一個單獨的方法可能更具可讀性。

4

是什麼讓你認爲把代碼分解成多個方法會損害可讀性?根據我的經驗,即使將中小尺寸的代碼拆分爲多個方法也可以大大提高可讀性。

2

我認爲你要找的術語是可變範圍 - 換句話說,你正在尋找方法來限制ij的範圍。但你不必擔心這一點。目前的問題需要創建單獨的方法 - 無論範圍考慮。

這樣可以提高可讀性,因爲它可以讓讀者從高層開始編碼,然後根據需要深入鑽取。它也將提高可測性,因爲你的小方法只能做一件事

def calc_first_nucleotide_position(po) 
    i = po.first 
    while nucleotide_at_position(i-1) == nucleotide_at_position(i) 
    raise "Assumption violated" if i == 1 
    i -= 1 
    end 
    i 
end 

# etc... 

first_nucleotide_position = calc_first_nucleotide_position(positions) 
last_nucleotide_position = calc_last_nucleotide_position(positions) 

# etc... 
1

如果你想要的是讓新的變數,從泄漏到您的程序的其餘部分,您可以使用1.times將代碼包裝在一個塊中。在塊內創建的任何新變量將在關閉塊時被破壞。請記住,一旦塊關閉,您對預先存在的變量所做的任何更改都會保留。

y = 20 
1.times do 
    # put your code in here 
    i = 1 
    puts x = y # => 20, because y is available from outside the block 
    y = 'new value' # We can change the value of y but our changes will 
    # propagate to outside the block since y was defined before we opened 
    # the block. 
end 

defined? i # => nil, i is lost when you close the block 
defined? x # => nil, x is also local to the block 
puts y # => 'new value'