2017-08-11 63 views
1

我有一個setter方法設置一個月。它需要返回一個字符串'01' - '12'。我希望ti能夠獲取數字和文本(包括3個月和全部月份,我正在通過輸入Aug來測試它,但無法使用ti,它將輸入日期設置爲與輸入日期相同(8月)不能讓setter方法工作

的代碼是

def month=(month) 
    # this can take a number or string, either with 3 char month or full month 
    # it returns a 2 char string, left padded with 0s 

    if !month.numeric? 
    case month.upcase[0,3] 
    when 'JAN' 
     month = '01' 
    when 'FEB' 
     month = '02' 
    when 'MAR' 
     month = '03' 
    when 'APR' 
     month = '04' 
    when 'MAY' 
     month = '05' 
    when 'JUN' 
     month = '06' 
    when 'JUL' 
     month = '07' 
    when 'AUG' 
     month = '08' 
    when 'SEP' 
     month = '09' 
    when 'OCT' 
     month = '10' 
    when 'NOV' 
     month = '11' 
    when 'DEC' 
     month = '12' 
    else 
     month = '00' 
    end 
    end if 
    @month=month.rjust(2, '0') 
end 

而且我與

event.month = "Aug" 
p event.month 

現在,這裏是真正的怪異位調用它。如果我增加AP線

  end if 
      p month 
      @month=month.rjust(2, '0') 
    end 

它打印「8月」,但該方法的工作原理,'p event.month'返回'08'剛剛被調用後

任何想法,我做錯了?

+0

什麼是「c字符串」? – sawa

+0

一個錯字,只是將其改爲字符串。對不起 –

+0

您是否考慮過使用[Date](https://ruby-doc.org/stdlib-2.3.1/libdoc/date/rdoc/Date.html)來獲取月份名稱?方法更容易,讓操作系統照顧本地化...嘗試'p Date :: ABBR_MONTHNAMES'並使用它代替24行代碼。 – dawg

回答

1

這是因爲你有名稱衝突。你有局部變量(方法的參數month),實例變量@month與設置器month=。當發生類似碰撞時,會使用最近的上下文。所以最近的上下文是month作爲局部變量,所以你實際上不改變類屬性,而是改變方法的參數。

只需重命名:

def month=(month) 

def month=(m) 

,一切都將正常工作。

+0

好吧,沒有意識到實例和局部變量必須有不同的名稱。謝謝。 –

+0

好吧,將月份更改爲m,但仍然出現相同(錯誤)的行爲。好了,稍微有點不同,現在如果我在方法中包含p月,它返回'08',方法重新運行'08',但是如果我沒有'p月的方法返回'Aug' –

+0

糾正, 好的,但仍然會出現相同(錯誤)的行爲。稍微有點不同,現在如果我在方法中包含'p月',它返回'08',方法返回'08',但如果我沒有'p月方法是返回'8月'(儘管'p月'方法也返回'08' –

3

該行end if應該只是end

尾隨if的出現意味着「除非滿足以下條件,否則不要運行此語句」,因此只有在您已經設置了@month實例變量後才能評估您的case語句。

這相當於它是

if @month=m.rjust(2, '0') 
    if !month.numeric? 
    case month.upcase[0,3] 
    # when/else statements 
    end 
    end 
end 

所以將其更改爲這樣:

end 
@month=month.rjust(2, '0') 

使你的代碼工作。

通過添加p month語句來調試,您會導致先計算,這樣的情況下語句運行(因爲p有一個返回值是truthy),其次爲@month分配,所以你的代碼正確運行訂購。

玩的時候,我注意到,如果你通過這個數字而不是一個數字字符串,.rjust會失敗,所以我建議改變,爲:

@month=month.to_s.rjust(2, '0') 

而且你case語句可以通過大大簡化保存結果的case的,而不是在每個when做任務:

m = case month.upcase[0,3] 
    when 'JAN' then '01' 
    when 'FEB' then '02' 
    #... 
    else '00' 
    end 

或者,你可以這樣做,以消除case語句完全是這樣的:

def month=(m) 
    if !m.numeric? 
    m = Date::ABBR_MONTHNAMES.index(m.capitalize[0,3]) 
    end 
    @month = m.to_s.rjust(2, '0') 
end 
+1

'Date :: ABBR_MONTHNAMES'爲名字... – dawg

+0

噢,很好,更新了我的簡體版本 – Unixmonkey

+0

LOL 。謝謝,我幾乎提到我要用一個數組來做,%w和index.present?對我來說是新的,在之前也沒有聽說過truthy這個術語;)。 但是ime仍然會返回「Aug」(使用第二個,最優雅的代碼);(。 –