Поскольку я занимаюсь довольно много с продолжительностью в моем приложении 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
Пройдите все, используя '' to_i' – oldergod
1 .month.class' лжет вам, это фактически 'ActiveSupport :: Duration', хотя он утверждает, что является' Fixnum'. Похоже, у лжи есть дыры. –
@oldergod Я считал, что использование to_i на самом деле не всегда одинаково. Например, Time.mktime (2013, 3, 6) - 1.month возвращает 6 февраля в качестве ответа, но Time.mktime (2013, 3, 6) - 1.month.to_i дает 4 февраля вместо этого – dominos