如何使用 String#between?使用 DateTime 对象在 Rails 中工作?
How does using String#between? with DateTime objects work in Rails?
使用 Ruby 2.3.2, Rails 5.0.0.1
在Ruby控制台中
2.3.2 :001 > date_time_str = "2015-01-08 08:17:15 UTC"
=> "2015-01-08 08:17:15 UTC"
2.3.2 :002 > date_time_range_start = "2015-01-08 08:16:15 UTC"
=> "2015-01-08 08:16:15 UTC"
2.3.2 :003 > date_time_range_end = "2015-01-08 08:20:15 UTC"
=> "2015-01-08 08:20:15 UTC"
2.3.2 :008 > require 'date'
=> true
2.3.2 :009 > date_time_str.between?(DateTime.parse(date_time_range_start), DateTime.parse(date_time_range_end))
ArgumentError: comparison of String with DateTime failed
from (irb):9:in `between?'
from (irb):9
from /home/jignesh/.rvm/rubies/ruby-2.3.2/bin/irb:11:in `<main>'
我在尝试将 String
实例与 DateTime
实例进行比较时预期会出现上述行为。但是,当我在 rails 控制台中尝试相同操作时,它 returns 预期结果如下所示。
在Rails控制台中
Loading development environment (Rails 5.0.0.1)
2.3.2 :001 > date_time_str = "2015-01-08 08:17:15 UTC"
=> "2015-01-08 08:17:15 UTC"
2.3.2 :002 > date_time_range_start = "2015-01-08 08:16:15 UTC"
=> "2015-01-08 08:16:15 UTC"
2.3.2 :003 > date_time_range_end = "2015-01-08 08:20:15 UTC"
=> "2015-01-08 08:20:15 UTC"
2.3.2 :004 > date_time_str.between?(DateTime.parse(date_time_range_start), DateTime.parse(date_time_range_end))
=> true
2.3.2 :005 > date_time_str_2 = "2015-01-08 08:21:15 UTC"
=> "2015-01-08 08:21:15 UTC"
2.3.2 :006 > date_time_str_2.between?(DateTime.parse(date_time_range_end), DateTime.parse(r_e))
=> false
任何人都可以帮助我了解 Rails 在内部做了什么来完成上述工作吗?
String#<=>
in ruby 试图将自己与另一个对象进行比较。如果另一个对象无法比较(不是字符串),则字符串的具体实现 (c-source here) 将另一个对象与接收字符串进行比较。
换句话说,"str" <=> obj
相当于
if obj.is_a?(String)
# compare bytes
elsif obj.respond_to?(:to_str)
obj = obj.to_str
# compare bytes
else
# a few safety checks
-1 * (obj <=> "str")
end
现在我们 "str" <=> obj
沸腾到 obj <=> "str"
。到目前为止,这只是 Ruby,没有 Rails。由于 Datetime#<=>
没有对字符串进行特殊处理,因此它 returns 为零,故事到此结束。
在Rails中,他们重新定义了Datetime#<=>
and defined String#to_datetime
使用 Ruby 2.3.2, Rails 5.0.0.1
在Ruby控制台中
2.3.2 :001 > date_time_str = "2015-01-08 08:17:15 UTC"
=> "2015-01-08 08:17:15 UTC"
2.3.2 :002 > date_time_range_start = "2015-01-08 08:16:15 UTC"
=> "2015-01-08 08:16:15 UTC"
2.3.2 :003 > date_time_range_end = "2015-01-08 08:20:15 UTC"
=> "2015-01-08 08:20:15 UTC"
2.3.2 :008 > require 'date'
=> true
2.3.2 :009 > date_time_str.between?(DateTime.parse(date_time_range_start), DateTime.parse(date_time_range_end))
ArgumentError: comparison of String with DateTime failed
from (irb):9:in `between?'
from (irb):9
from /home/jignesh/.rvm/rubies/ruby-2.3.2/bin/irb:11:in `<main>'
我在尝试将 String
实例与 DateTime
实例进行比较时预期会出现上述行为。但是,当我在 rails 控制台中尝试相同操作时,它 returns 预期结果如下所示。
在Rails控制台中
Loading development environment (Rails 5.0.0.1)
2.3.2 :001 > date_time_str = "2015-01-08 08:17:15 UTC"
=> "2015-01-08 08:17:15 UTC"
2.3.2 :002 > date_time_range_start = "2015-01-08 08:16:15 UTC"
=> "2015-01-08 08:16:15 UTC"
2.3.2 :003 > date_time_range_end = "2015-01-08 08:20:15 UTC"
=> "2015-01-08 08:20:15 UTC"
2.3.2 :004 > date_time_str.between?(DateTime.parse(date_time_range_start), DateTime.parse(date_time_range_end))
=> true
2.3.2 :005 > date_time_str_2 = "2015-01-08 08:21:15 UTC"
=> "2015-01-08 08:21:15 UTC"
2.3.2 :006 > date_time_str_2.between?(DateTime.parse(date_time_range_end), DateTime.parse(r_e))
=> false
任何人都可以帮助我了解 Rails 在内部做了什么来完成上述工作吗?
String#<=>
in ruby 试图将自己与另一个对象进行比较。如果另一个对象无法比较(不是字符串),则字符串的具体实现 (c-source here) 将另一个对象与接收字符串进行比较。
换句话说,"str" <=> obj
相当于
if obj.is_a?(String)
# compare bytes
elsif obj.respond_to?(:to_str)
obj = obj.to_str
# compare bytes
else
# a few safety checks
-1 * (obj <=> "str")
end
现在我们 "str" <=> obj
沸腾到 obj <=> "str"
。到目前为止,这只是 Ruby,没有 Rails。由于 Datetime#<=>
没有对字符串进行特殊处理,因此它 returns 为零,故事到此结束。
在Rails中,他们重新定义了Datetime#<=>
and defined String#to_datetime