2012-04-18 96 views
2

我有一個非常簡單的Ruby問題。有沒有辦法來重構這個:Ruby如果語句重構

<%= some_array.length if some_array.length > 1 %> 

成類似

<%= some_array.length if self > 1 %> 

其中「自我」(例如)是引用最初計算值 - 即some_array.length?

+0

這屬於[代碼評論](http://codereview.stackexchange.com/)。 – 2012-04-18 15:33:53

+1

@Matheus,我會說這是好的,這是一個非常具體的用例,而不是代碼審查。 – tokland 2012-04-18 15:38:22

回答

1

我喜歡保持主模板簡單,拉成邏輯的幫手。再培訓局可包含:

<%= display_length(some_array) %> 

當助手包含:

def display_length(array) 
    array.length if array.length > 1 
end 

當然,調整的名字最能代表你的業務邏輯。

5

不,你不能這樣做。該聲明不按照您假設的方式從左到右評估。 if語句首先被評估,所以沒有「自我」來測試。如您所說,「最初計算的值」是第一個if聲明。

+0

我有這樣的感覺。 @馬克托馬斯:我最終使用你的方法。感謝這兩個! – neon 2012-04-20 18:58:53

1

,如果你不想計算它2次,你可以做這樣的

<% len = some_array.length %> 
<%= len if len > 1 %> 

其他你可以創建的helper方法。 最初的問題是有點誤導,因爲左側的,如果不會被右側前計算所以,即使你可以通過「你的自我」爲計算值想象(你的僞代碼):

people.destroy_all if self > 100 

這將計算的破壞始終以生產 「你的自我」:d

0

答:您可以做這樣的事情

<%= l = some_array.length if l > 1 %> 

B.可以使用Presenter pattern

0

也許:

length if (length = some_array.length) > 1 

有點深奧,但較短的...

+0

恐怕'length'會得到'some_array.length> 1'的結果(true或false)。你需要將它加括號。 – 2012-04-18 16:02:12

+0

好點,謝謝!轉移的paran – 2012-04-18 17:34:53

-2
class Object 
    def block_scope 
    yield self 
    [] # Required for HAML and probably ERB as well 
    end 
end 

ERB:

<% array.length.block_scope do |l| %> 
    <%= l if l > 1 %> 
<% end %> 

HAML:

- array.length.block_scope do |l| 
    = l if l > 1 

好一點視覺上較簡單的任務

UPDATE

同意,加入block_scopeObject命名空間是意見肯定矯枉過正,更好的解決辦法是建立一個幫手:

def block_scope(*args) 
    yield *args 
    [] #? 
end 

- block_scope(array.length) do |l| 
    = l if l > 1 
+1

這是一個完全怪誕的解決方案。它比簡單的'if'語句更冗長,並且具有非常嚴重的副作用,即用99.999%的時間無用的一般命名方法污染每個單個對象。它不能實現減少輸入或減少對'array.length'的評估。就「視覺上更好」而言,這是非常主觀的,但我認爲在這一點上你也錯了;這是醜陋的罪過。這種事情是助手的目的。對不起,如果這聽起來很刺耳,但重要的是要確保新的Rubyists不認爲這是一個好的解決方案。 – meagar 2012-04-18 17:21:21

+0

@meagar我的確完成了更少的評估(儘管數組長度沒有多大意義),除了一般我們不是在討論單行塊,它可以用於更大的塊,尤其是在參數解構方面。儘管如此,這個例子還不清楚。 – 2012-04-18 18:03:52

0

你能做的最好的是更多的東西或多或少這樣的:

t = some_array.length; t if t > 1 

此外,請注意,有條件(無else)的插值ERB表達式將在一種情況下返回值,在另一種情況下將返回nil。 ERB的實施將評估result.to_s#to_s,nil產生「」。所以,這是一個可行的設計模式,但可能不會被後面所有的代碼閱讀器輕易理解。