2017-08-11 66 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”(使用第二个,最优雅的代码);(。 –