Ada*_*sek 19 ruby datetime parsing
我在控制器操作中有两个日期参数,如果它们是nil,或者解析失败,我想回退到默认值.
不幸的是,DateTime.strptime如果解析失败,它似乎抛出一个异常,这迫使我写下这个怪物:
starting = if params[:starting].present?
begin
DateTime.strptime(params[:starting], "%Y-%m-%d")
rescue
@meeting_range.first
end
else
@meeting_range.first
end
Run Code Online (Sandbox Code Playgroud)
感觉坏人.有没有办法用Ruby stdlib解析一个不需要begin...rescue块的日期?对于这种情况,慢性感觉有点矫枉过正.
eco*_*gic 21
一般来说,我不能同意其他解决方案,使用rescue这种方式是不好的做法.我认为值得一提的是,有人试图将这个概念应用于不同的实现.
我担心的是,你可能会感兴趣的其他一些例外将被隐藏rescue,打破了早期的错误检测规则.
以下是Date没有,DateTime但你会明白:
Date.parse(home.build_time) # where build_time does not exist or home is nil
Date.parse(calculated_time) # with any exception in calculated_time
Run Code Online (Sandbox Code Playgroud)
不得不面对同样的问题,我最终修补了Ruby如下:
# date.rb
class Date
def self.safe_parse(value, default = nil)
Date.parse(value.to_s)
rescue ArgumentError
default
end
end
Run Code Online (Sandbox Code Playgroud)
在进入方法之前,任何值的异常都会上升,并且只会ArgumentError被捕获(尽管我不知道任何其他可能的异常).
内联的唯一正确使用rescue类似于:
f(x) rescue handle($!)
Run Code Online (Sandbox Code Playgroud)
更新
这些天,我宁愿没有猴子补丁红宝石.相反,我将我包装Date在一个Rich模块中,我将其放入lib/rich,然后用以下方法调用它:
Rich::Date.safe_parse(date)
Run Code Online (Sandbox Code Playgroud)
Ama*_*dan 19
为什么不简单:
starting = DateTime.strptime(params[:starting], '%Y-%m-%d') rescue @meeting_range.first
Run Code Online (Sandbox Code Playgroud)
如今我首选的方法是用于 Dry::Types类型强制和Dry::Monads表示错误。
require "dry/types"
require "dry/monads"
Dry::Types.load_extensions(:monads)
Types = Dry::Types(default: :strict)
Types::Date.try("2021-07-27T12:23:19-05:00")
# => Success(Tue, 27 Jul 2021)
Types::Date.try("foo")
# => Failure(ConstraintError: "foo" violates constraints (type?(Date, "foo"))
Run Code Online (Sandbox Code Playgroud)