2009-11-30 39 views
12

Ok, vì vậy tôi muốn tạo một băm có băm rỗng làm giá trị mặc định. Một chút kỳ lạ, tôi biết, nhưng hãy nói rằng tôi nghĩ rằng nó có thể hữu ích.Tại sao Hash.new ({}) ẩn thành viên băm?

Vì vậy, đây là những gì tôi đã làm:

>> a = Hash.new({}) 
=> {} 
>> a[:a][:b] = 5 
=> 5 
>> a 
=> {} 
>> a[:a] 
=> {:b=>5} 
>> a.keys 
=> [] 
>> a.size 
=> 0 
>> a[:a].size 
=> 1 

Nói cách khác, tôi không thấy thành viên băm khi tôi kiểm tra việc băm, nhưng tôi có thể truy cập nó bằng chính nó.

Hành vi này có được mong đợi không? Chuyện gì đang xảy ra ở đây?

BTW, đây là Ruby 1.9.1, chưa thử các phiên bản cũ hơn.

Edit: đơn giản hóa ví dụ như nó không phải là một băm băm băm ...

+0

Cũng có thể sao chép trên 1.8.7. –

Trả lời

17

Dự kiến ​​hành vi (trên tất cả các phiên bản ruby). Và nếu bạn thử nghiệm một chút nữa, bạn sẽ thấy rằng bạn luôn truy cập vào cùng bảng băm, cho dù chính bạn sử dụng:

>> a[:a][:b] = 1 
=> 1 
>> a[:c][:d] = 2 
=> 2 
>> a[:d] 
=> {:b=>1, :d=>2} 

Cách Hash.new với một đối số mặc định làm việc là: Nếu bạn làm hash[key] nó kiểm tra xem khóa đó có tồn tại trong băm hay không. Nếu có, nó sẽ trả về giá trị cho khóa đó. Nếu không, nó sẽ trả về giá trị mặc định. Nó không thêm khóa vào băm và nó sẽ trả về cùng một đối tượng mặc định (không phải bản sao) mỗi lần.

Để nhận được những gì bạn muốn, thay vào đó bạn muốn chỉ định một khối mặc định. Bằng cách đó, khối sẽ được thực hiện mỗi khi bạn truy cập một khóa không có trong băm. Bên trong khối bạn có thể tạo một Hash mới và đặt khóa thành "point" thành hash đó. Giống như vậy:

Hash.new { |h,k| h[k] = {} } 
+0

Vì vậy, về cơ bản, ông đã thêm các khóa vào giá trị mặc định, chứ không phải băm của mình. – Riking

Các vấn đề liên quan