2013-07-29 5 views
2

레일스 앱에서 기간이 상당히 길어 졌기 때문에 일부 지역에서는 해시 키로 사용하고 싶습니다. 그러나, 그것은 나를 위해 예상대로 작동하지 않는 것 같습니다.레일에서 해시 키로 기간 사용하기

초기 해시를 만드는 것이 좋습니다. 예를 들어, 다음은 작동합니다

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

>> hash[1.month] 
=> nil 

일부 추가 조사 나에게 그 이유를 보여 주었다 :

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

그러나, 해시에서 값을 검색하는 것은 불가능합니다

꽤 예기치 않았던 어느 쪽이

더욱이,이 물건이 differe fixNum 클래스의 일반 오브젝트에 ntly 지정합니다. 정상 Fixnum이라는 객체의 경우, OBJECT_ID의 값이 항상 같은, 예를 들면 것으로 보인다 : 그들은

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

그래서 같은 클래스에서 비록 재생 시간에 대한

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

이 그것은, 다른 객체가 항상 다른 것처럼 보이는데, 이것이 해시가 작동하지 않는 이유입니다. 유일한 해결책은 정확히 같은 개체에 액세스 할 수 있습니다 : 당신이 동적으로 생성 기간을 가진 개체의 많은 경우

>> 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과 같은) 기능이 계속 작동해야한다는 것입니다. 참고로

: 내 루비 버전 - 2.3.18 대의

+2

지속 시간 얻을 것은 – oldergod

+1

'1 to_i''사용하여 모든 것을 전달 .month.class'는 거짓말입니다. 실제로 Fixnum이라고 주장하더라도 실제로는 ActiveSupport :: Duration입니다. 거짓말처럼 구멍이 나있는 것처럼 보입니다. –

+0

@oldergod 나는 to_i를 사용하는 것이 실제로 항상 똑같지는 않다고 생각했다. 예를 들어 Time.mktime (2013, 3, 6) - 1 월은 2 월 6 일을 답으로, Time.mktime (2013, 3, 6) 1.month.to_i는 대신 2 월 4 일을 제공합니다. – dominos

답변

0

와우, 이상한 발견입니다 - 1.8.7은 버전을 레일. 이 작업을 수행, 나는 그것을 깰 수 없었던,하지만 조금 깨지기 쉬운 것 같다

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]