警告:猴子修補核心Ruby的功能可能是危險的,尤其是在這種情況下,因爲許多開發商有一種期待什麼樣的行爲的Time
和Date
對象與+
和Fixnum
s工作時有。如果您使用來滾動您自己的解決方案,則沒有已知的文件庫依賴於此預期行爲,您可以利用此答案。否則,由於不準確的對象或隨機不需要的異常導致未知邊緣情況,你正在進入一個受到傷害的世界。
這實際上是Date
對象的行爲與核心Ruby庫的行爲Time
對象的行爲。 A DateTime
對象是Date
的擴展,而Rails只是extends it a bit further。
這裏是method reference for Date#+
,其中規定:
返回後,自我指向其他天的日期對象。另一個應該是一個數值。如果另一個是flonum,則假定它的精確度至多爲納秒。
鑑於method reference for Time#+
表現不同:
添加的秒一些號碼(可能是分數),以時間和返回該值作爲一個新的Time
對象。
這兩種行爲都是用C語言編寫的Ruby核心和庫方法,但是可以在Ruby中將這種核心行爲進行猴子修補。例如,猴補丁DateTime
還加入了Fixnum
到它時,表現得與秒:
class DateTime
def +(num)
num = num.to_f/(3600*24) if num.class == Fixnum
super(num)
end
end
演示:
[email protected]:/vagrant$ irb
2.1.2 :001 > require 'date'
=> true
2.1.2 :002 > class DateTime
2.1.2 :003?> def +(num)
2.1.2 :004?> num = num.to_f/(3600*24) if num.class == Fixnum
2.1.2 :005?> super(num)
2.1.2 :006?> end
2.1.2 :007?> end
=> :+
2.1.2 :008 > test = DateTime.now
=> #<DateTime: 2015-11-25T12:09:18-05:00 ((2457352j,61758s,869355861n),-18000s,2299161j)>
2.1.2 :009 > test + 1
=> #<DateTime: 2015-11-25T12:09:19-05:00 ((2457352j,61759s,869355861n),-18000s,2299161j)>
爲了解決您的編輯,因爲你希望它會是同樣的方法是什麼。簡單地覆蓋類,提高異常,如果檢測到的參數是Fixnum
:
class Time
def +(num)
raise TypeError.new("No implicit conversion of Fixnum into Time") if num.class == Fixnum
super(num)
end
end
class Date
def +(num)
raise TypeError.new("No implicit conversion of Fixnum into Date") if num.class == Fixnum
super(num)
end
end
class DateTime
def +(num)
raise TypeError.new("No implicit conversion of Fixnum into DateTime") if num.class == Fixnum
super(num)
end
end
什麼?這些語句都不會是「真」的,因爲每個生成的'now'都會以毫秒爲單位關閉。 – sjagr
是的,你說得對。我糾正了這個問題 –
**使用猴子補丁修改任何語言的核心庫的功能是非常危險的**你正在尋求複雜的道路,無論是你自己還是新的開發人員在'DateTime'不'工作應該如何。 –