2012-01-04 3 views
0

Я не понимаю, как работают рубины Ruby.Каковы значения, сопоставленные с?

Я ожидаю, что они:

a = 'a' 
{a => 1}[a] # => 1 
{a: 1}[:a] # => 1 
{2 => 1}[2] # => 1 

Как это работает?

{'a' => 1}['a'] # => 1 

Первая строка 'a' не является тем же объектом, как второй строки 'a'.

ответ

1
some_hash[k] = v 

В основном, когда вы сделаете это, то, что хранится в не прямая связь k => v. Вместо этого k запрашивается hash code, который затем используется для отображения на v.

Равные значения дают равные хэш-коды. Вот почему ваш последний пример работает так, как он делает.

Несколько примеров:

1.9.3p0 :001 > s = 'string' 
=> "string" 
1.9.3p0 :002 > 'string'.hash 
=> -895223107629439507 
1.9.3p0 :003 > 'string'.hash == s.hash 
=> true 
1.9.3p0 :004 > 2.hash 
=> 2271355725836199018 
1.9.3p0 :005 > nil.hash 
=> 2199521878082658865 
+3

Существует еще сравнение происходит , просто не с равными ?. Хэш просто используется для размещения значений в ковши, для устранения столкновений необходимы сравнения ключей. –

+0

Да, вы правы. Ваш ответ дополняет мой :-) –

+0

-1. Хешинг не имеет к этому никакого отношения; контейнер на основе BST может демонстрировать то же самое поведение. –

3

Рубин не использует объект равенства (equal?) для сравнения хэш-ключи. Было бы не очень полезно, если бы это произошло в конце концов.

Вместо этого он использует eql?, что для строк такая же, как ==

3

В качестве сноски на другие ответы, вы можете позволить хэш вести себя, как вы ожидали:

h = {'a'=> 1} 
p h['a'] #=> 1 
h.compare_by_identity 
p h['a'] #=> nil ; not the same object 
+0

Я уже нашел это, но спасибо!) – meandre

Смежные вопросы