2013-07-29 15 views
2

因为我在Rails应用中处理了很多持续时间,所以我还想在某些地方将它们用作哈希键。但是,它似乎没有像我预期的那样工作。在Rails中使用持续时间作为哈希键

创建初始哈希工作正常。例如,下面的工作:

>> hash = {1.week => 'abc', 1.month => 'def'} 

然而,从散列检索值是不可能的:

>> hash[1.month] 
=> nil 

一些进一步的调查表明,我这样做的原因:

>> 1.week.eql? 1.week 
=> false 

这是非常意想不到的

此外,它似乎像这些对象表现不同定位到FixNum类的普通对象。对于正常Fixnum对象的对象中,OBJECT_ID的价值似乎总是相同的,例如:

>> 15.object_id 
=> 31 
>> 15.object_id 
=> 31 

如果持续时间,这是不同的,虽然他们是同一类

>> 1.month.class 
=> Fixnum 
>> 1.month.object_id 
=> 70305513092140 
>> 1.month.object_id 
=> 70305513086860 

所以,似乎对象总是不同的,这就是为什么哈希不起作用。唯一的办法是用完全相同的对象来访问:

>> a = 1.month 
=> 1 month 
>> hash = {a => 'b'} 
=> {1 month=>"b"} 
>> hash[a] 
=> "b" 

显然,如果你有很多与动态创建的持续时间的对象,这是不可能的。

的持续时间分组无法正常工作或:

>> limits.group_by(&:duration) 
=> #<OrderedHash {1 month=>[#<Limit:0x7fe28e441380>], 1 month=>[#<Limit:0x7fe28e4290c8>]}> 

所以,我想知道是否有可能获得持续工作作为哈希键不知何故?到目前为止,我还没有找到一个好的解决方案,我不确定是否有一个。重要的是像(Time.now - duration)这样的函数应该继续工作。

FYI:我的红宝石版本 - 1.8.7,Rails的版本 - 2.3.18

+2

使用'to_i' – oldergod

+1

'1传的一切.month.class'对你说谎,它实际上是一个'ActiveSupport :: Duration',即使它声称是'Fixnum'。看起来谎言有一些漏洞。 –

+0

@oldergod我认为,但使用to_i实际上并不总是一样。例如Time.mktime(2013,3,6) - 1.month返回6月2日作为答案,但Time.mktime(2013,3,6) - 1.month.to_i改为2月4日 – dominos

回答

0

哇,这是一个奇怪的发现。这样做的工作,我一直没能打破它,但它似乎有点脆弱:

hash = {1.year.inspect => "val1", 2.month.inspect => "val2", (1.year-4.days).inspect => "val3"} 
=> {"1 year"=>"val1", "2 months"=>"val2", "1 year and -4 days"=>"val3"} 

hash[2.months.inspect] 
=> "val2" 

hash[(1.year-4.days).inspect] 
=> "val3" 

,并获得持续时间回来

hash.keys.collect{|k| eval(k.gsub(" and ","+").split(" ").join("."))} 
=> [1 year, 2 months, 1 year and -4 days] 
相关问题