hamster 1.0.1.pre.rc3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hamster.rb +2 -0
  3. data/lib/hamster/associable.rb +49 -0
  4. data/lib/hamster/core_ext/enumerable.rb +3 -13
  5. data/lib/hamster/core_ext/io.rb +1 -1
  6. data/lib/hamster/core_ext/struct.rb +9 -0
  7. data/lib/hamster/deque.rb +57 -38
  8. data/lib/hamster/enumerable.rb +14 -41
  9. data/lib/hamster/experimental/mutable_queue.rb +5 -8
  10. data/lib/hamster/experimental/mutable_set.rb +6 -7
  11. data/lib/hamster/hash.rb +301 -110
  12. data/lib/hamster/immutable.rb +1 -1
  13. data/lib/hamster/list.rb +479 -194
  14. data/lib/hamster/mutable_hash.rb +6 -7
  15. data/lib/hamster/nested.rb +78 -0
  16. data/lib/hamster/read_copy_update.rb +1 -1
  17. data/lib/hamster/set.rb +198 -88
  18. data/lib/hamster/sorted_set.rb +706 -261
  19. data/lib/hamster/trie.rb +134 -15
  20. data/lib/hamster/vector.rb +571 -140
  21. data/lib/hamster/version.rb +3 -1
  22. data/spec/lib/hamster/associable/associable_spec.rb +150 -0
  23. data/spec/lib/hamster/core_ext/array_spec.rb +1 -1
  24. data/spec/lib/hamster/core_ext/enumerable_spec.rb +2 -2
  25. data/spec/lib/hamster/core_ext/io_spec.rb +1 -1
  26. data/spec/lib/hamster/deque/clear_spec.rb +3 -3
  27. data/spec/lib/hamster/deque/construction_spec.rb +8 -8
  28. data/spec/lib/hamster/deque/copying_spec.rb +1 -1
  29. data/spec/lib/hamster/deque/dequeue_spec.rb +12 -4
  30. data/spec/lib/hamster/deque/empty_spec.rb +14 -16
  31. data/spec/lib/hamster/deque/enqueue_spec.rb +4 -4
  32. data/spec/lib/hamster/deque/first_spec.rb +18 -0
  33. data/spec/lib/hamster/deque/inspect_spec.rb +1 -1
  34. data/spec/lib/hamster/deque/last_spec.rb +9 -11
  35. data/spec/lib/hamster/deque/marshal_spec.rb +6 -6
  36. data/spec/lib/hamster/deque/new_spec.rb +5 -5
  37. data/spec/lib/hamster/deque/pop_spec.rb +15 -3
  38. data/spec/lib/hamster/deque/pretty_print_spec.rb +24 -0
  39. data/spec/lib/hamster/deque/push_spec.rb +37 -0
  40. data/spec/lib/hamster/deque/shift_spec.rb +30 -0
  41. data/spec/lib/hamster/deque/size_spec.rb +1 -1
  42. data/spec/lib/hamster/deque/to_a_spec.rb +2 -2
  43. data/spec/lib/hamster/deque/to_ary_spec.rb +1 -1
  44. data/spec/lib/hamster/deque/to_list_spec.rb +3 -3
  45. data/spec/lib/hamster/deque/unshift_spec.rb +8 -3
  46. data/spec/lib/hamster/experimental/mutable_set/add_qm_spec.rb +3 -3
  47. data/spec/lib/hamster/experimental/mutable_set/add_spec.rb +3 -3
  48. data/spec/lib/hamster/experimental/mutable_set/delete_qm_spec.rb +3 -3
  49. data/spec/lib/hamster/experimental/mutable_set/delete_spec.rb +3 -3
  50. data/spec/lib/hamster/hash/all_spec.rb +32 -34
  51. data/spec/lib/hamster/hash/any_spec.rb +34 -36
  52. data/spec/lib/hamster/hash/assoc_spec.rb +3 -3
  53. data/spec/lib/hamster/hash/clear_spec.rb +4 -4
  54. data/spec/lib/hamster/hash/construction_spec.rb +8 -8
  55. data/spec/lib/hamster/hash/copying_spec.rb +1 -1
  56. data/spec/lib/hamster/hash/default_proc_spec.rb +3 -3
  57. data/spec/lib/hamster/hash/delete_spec.rb +4 -4
  58. data/spec/lib/hamster/hash/each_spec.rb +3 -3
  59. data/spec/lib/hamster/hash/each_with_index_spec.rb +1 -1
  60. data/spec/lib/hamster/hash/empty_spec.rb +13 -15
  61. data/spec/lib/hamster/hash/eql_spec.rb +4 -4
  62. data/spec/lib/hamster/hash/except_spec.rb +7 -7
  63. data/spec/lib/hamster/hash/fetch_spec.rb +10 -10
  64. data/spec/lib/hamster/hash/find_spec.rb +2 -2
  65. data/spec/lib/hamster/hash/flat_map_spec.rb +4 -4
  66. data/spec/lib/hamster/hash/flatten_spec.rb +13 -13
  67. data/spec/lib/hamster/hash/get_spec.rb +7 -7
  68. data/spec/lib/hamster/hash/has_key_spec.rb +3 -3
  69. data/spec/lib/hamster/hash/has_value_spec.rb +4 -4
  70. data/spec/lib/hamster/hash/hash_spec.rb +5 -5
  71. data/spec/lib/hamster/hash/inspect_spec.rb +2 -2
  72. data/spec/lib/hamster/hash/invert_spec.rb +6 -6
  73. data/spec/lib/hamster/hash/key_spec.rb +2 -2
  74. data/spec/lib/hamster/hash/keys_spec.rb +2 -2
  75. data/spec/lib/hamster/hash/map_spec.rb +4 -4
  76. data/spec/lib/hamster/hash/marshal_spec.rb +2 -2
  77. data/spec/lib/hamster/hash/merge_spec.rb +62 -56
  78. data/spec/lib/hamster/hash/min_max_spec.rb +9 -13
  79. data/spec/lib/hamster/hash/new_spec.rb +6 -6
  80. data/spec/lib/hamster/hash/none_spec.rb +3 -3
  81. data/spec/lib/hamster/hash/partition_spec.rb +2 -2
  82. data/spec/lib/hamster/hash/put_spec.rb +29 -7
  83. data/spec/lib/hamster/hash/reduce_spec.rb +4 -4
  84. data/spec/lib/hamster/hash/{remove_spec.rb → reject_spec.rb} +7 -7
  85. data/spec/lib/hamster/hash/reverse_each_spec.rb +1 -1
  86. data/spec/lib/hamster/hash/{filter_spec.rb → select_spec.rb} +6 -6
  87. data/spec/lib/hamster/hash/size_spec.rb +3 -3
  88. data/spec/lib/hamster/hash/slice_spec.rb +4 -4
  89. data/spec/lib/hamster/hash/sort_spec.rb +2 -2
  90. data/spec/lib/hamster/hash/store_spec.rb +29 -7
  91. data/spec/lib/hamster/hash/take_spec.rb +2 -2
  92. data/spec/lib/hamster/hash/to_a_spec.rb +1 -1
  93. data/spec/lib/hamster/hash/to_hash_spec.rb +4 -4
  94. data/spec/lib/hamster/hash/values_at_spec.rb +3 -3
  95. data/spec/lib/hamster/hash/values_spec.rb +2 -2
  96. data/spec/lib/hamster/immutable/new_spec.rb +14 -0
  97. data/spec/lib/hamster/list/add_spec.rb +16 -10
  98. data/spec/lib/hamster/list/all_spec.rb +33 -35
  99. data/spec/lib/hamster/list/any_spec.rb +29 -31
  100. data/spec/lib/hamster/list/append_spec.rb +6 -6
  101. data/spec/lib/hamster/list/at_spec.rb +1 -1
  102. data/spec/lib/hamster/list/break_spec.rb +4 -4
  103. data/spec/lib/hamster/list/cadr_spec.rb +9 -9
  104. data/spec/lib/hamster/list/chunk_spec.rb +5 -5
  105. data/spec/lib/hamster/list/clear_spec.rb +3 -3
  106. data/spec/lib/hamster/list/combination_spec.rb +3 -3
  107. data/spec/lib/hamster/list/compact_spec.rb +3 -3
  108. data/spec/lib/hamster/list/compare_spec.rb +3 -3
  109. data/spec/lib/hamster/list/cons_spec.rb +15 -17
  110. data/spec/lib/hamster/list/construction_spec.rb +20 -27
  111. data/spec/lib/hamster/list/copying_spec.rb +1 -1
  112. data/spec/lib/hamster/list/count_spec.rb +1 -1
  113. data/spec/lib/hamster/list/cycle_spec.rb +4 -4
  114. data/spec/lib/hamster/list/delete_at_spec.rb +4 -4
  115. data/spec/lib/hamster/list/drop_spec.rb +3 -3
  116. data/spec/lib/hamster/list/drop_while_spec.rb +3 -3
  117. data/spec/lib/hamster/list/each_slice_spec.rb +5 -5
  118. data/spec/lib/hamster/list/each_spec.rb +26 -28
  119. data/spec/lib/hamster/list/each_with_index_spec.rb +1 -1
  120. data/spec/lib/hamster/list/empty_spec.rb +13 -15
  121. data/spec/lib/hamster/list/eql_spec.rb +21 -21
  122. data/spec/lib/hamster/list/fill_spec.rb +8 -8
  123. data/spec/lib/hamster/list/find_all_spec.rb +3 -3
  124. data/spec/lib/hamster/list/find_index_spec.rb +1 -1
  125. data/spec/lib/hamster/list/find_spec.rb +1 -1
  126. data/spec/lib/hamster/list/flat_map_spec.rb +2 -2
  127. data/spec/lib/hamster/list/flatten_spec.rb +5 -5
  128. data/spec/lib/hamster/list/grep_spec.rb +4 -4
  129. data/spec/lib/hamster/list/group_by_spec.rb +6 -6
  130. data/spec/lib/hamster/list/hash_spec.rb +2 -2
  131. data/spec/lib/hamster/list/head_spec.rb +1 -1
  132. data/spec/lib/hamster/list/include_spec.rb +2 -2
  133. data/spec/lib/hamster/list/index_spec.rb +38 -0
  134. data/spec/lib/hamster/list/indices_spec.rb +62 -0
  135. data/spec/lib/hamster/list/init_spec.rb +3 -3
  136. data/spec/lib/hamster/list/inits_spec.rb +3 -3
  137. data/spec/lib/hamster/list/insert_spec.rb +1 -1
  138. data/spec/lib/hamster/list/inspect_spec.rb +1 -1
  139. data/spec/lib/hamster/list/intersperse_spec.rb +3 -3
  140. data/spec/lib/hamster/list/join_spec.rb +5 -5
  141. data/spec/lib/hamster/list/last_spec.rb +1 -1
  142. data/spec/lib/hamster/list/ltlt_spec.rb +20 -0
  143. data/spec/lib/hamster/list/map_spec.rb +4 -4
  144. data/spec/lib/hamster/list/maximum_spec.rb +24 -26
  145. data/spec/lib/hamster/list/merge_by_spec.rb +10 -10
  146. data/spec/lib/hamster/list/merge_spec.rb +10 -10
  147. data/spec/lib/hamster/list/minimum_spec.rb +24 -26
  148. data/spec/lib/hamster/list/multithreading_spec.rb +6 -6
  149. data/spec/lib/hamster/list/none_spec.rb +5 -5
  150. data/spec/lib/hamster/list/one_spec.rb +5 -5
  151. data/spec/lib/hamster/list/partition_spec.rb +8 -8
  152. data/spec/lib/hamster/list/permutation_spec.rb +8 -8
  153. data/spec/lib/hamster/list/pop_spec.rb +3 -3
  154. data/spec/lib/hamster/list/product_spec.rb +1 -1
  155. data/spec/lib/hamster/list/reduce_spec.rb +5 -48
  156. data/spec/lib/hamster/list/{remove_spec.rb → reject_spec.rb} +4 -4
  157. data/spec/lib/hamster/list/reverse_spec.rb +3 -3
  158. data/spec/lib/hamster/list/rotate_spec.rb +7 -7
  159. data/spec/lib/hamster/list/sample_spec.rb +1 -1
  160. data/spec/lib/hamster/list/select_spec.rb +3 -3
  161. data/spec/lib/hamster/list/size_spec.rb +1 -1
  162. data/spec/lib/hamster/list/slice_spec.rb +123 -123
  163. data/spec/lib/hamster/list/sorting_spec.rb +5 -5
  164. data/spec/lib/hamster/list/span_spec.rb +5 -5
  165. data/spec/lib/hamster/list/split_at_spec.rb +4 -4
  166. data/spec/lib/hamster/list/subsequences_spec.rb +1 -1
  167. data/spec/lib/hamster/list/sum_spec.rb +1 -1
  168. data/spec/lib/hamster/list/tail_spec.rb +4 -4
  169. data/spec/lib/hamster/list/tails_spec.rb +3 -3
  170. data/spec/lib/hamster/list/take_spec.rb +3 -3
  171. data/spec/lib/hamster/list/take_while_spec.rb +4 -4
  172. data/spec/lib/hamster/list/to_a_spec.rb +2 -2
  173. data/spec/lib/hamster/list/to_ary_spec.rb +1 -1
  174. data/spec/lib/hamster/list/to_list_spec.rb +1 -1
  175. data/spec/lib/hamster/list/to_set_spec.rb +1 -1
  176. data/spec/lib/hamster/list/union_spec.rb +4 -4
  177. data/spec/lib/hamster/list/uniq_spec.rb +23 -19
  178. data/spec/lib/hamster/list/zip_spec.rb +5 -5
  179. data/spec/lib/hamster/nested/construction_spec.rb +103 -0
  180. data/spec/lib/hamster/set/add_spec.rb +13 -11
  181. data/spec/lib/hamster/set/all_spec.rb +32 -34
  182. data/spec/lib/hamster/set/any_spec.rb +32 -34
  183. data/spec/lib/hamster/set/clear_spec.rb +3 -3
  184. data/spec/lib/hamster/set/compact_spec.rb +3 -3
  185. data/spec/lib/hamster/set/construction_spec.rb +3 -3
  186. data/spec/lib/hamster/set/copying_spec.rb +1 -1
  187. data/spec/lib/hamster/set/count_spec.rb +1 -1
  188. data/spec/lib/hamster/set/delete_spec.rb +8 -8
  189. data/spec/lib/hamster/set/difference_spec.rb +8 -8
  190. data/spec/lib/hamster/set/disjoint_spec.rb +1 -1
  191. data/spec/lib/hamster/set/each_spec.rb +2 -2
  192. data/spec/lib/hamster/set/empty_spec.rb +15 -17
  193. data/spec/lib/hamster/set/eqeq_spec.rb +3 -3
  194. data/spec/lib/hamster/set/eql_spec.rb +3 -3
  195. data/spec/lib/hamster/set/exclusion_spec.rb +7 -7
  196. data/spec/lib/hamster/set/find_spec.rb +2 -2
  197. data/spec/lib/hamster/set/first_spec.rb +29 -0
  198. data/spec/lib/hamster/set/flatten_spec.rb +9 -9
  199. data/spec/lib/hamster/set/grep_spec.rb +1 -1
  200. data/spec/lib/hamster/set/group_by_spec.rb +12 -12
  201. data/spec/lib/hamster/set/hash_spec.rb +3 -3
  202. data/spec/lib/hamster/set/include_spec.rb +8 -8
  203. data/spec/lib/hamster/set/inspect_spec.rb +2 -2
  204. data/spec/lib/hamster/set/intersect_spec.rb +1 -1
  205. data/spec/lib/hamster/set/intersection_spec.rb +13 -13
  206. data/spec/lib/hamster/set/join_spec.rb +6 -6
  207. data/spec/lib/hamster/set/map_spec.rb +7 -7
  208. data/spec/lib/hamster/set/marshal_spec.rb +2 -2
  209. data/spec/lib/hamster/set/maximum_spec.rb +22 -24
  210. data/spec/lib/hamster/set/minimum_spec.rb +22 -24
  211. data/spec/lib/hamster/set/new_spec.rb +5 -5
  212. data/spec/lib/hamster/set/none_spec.rb +5 -5
  213. data/spec/lib/hamster/set/one_spec.rb +6 -6
  214. data/spec/lib/hamster/set/partition_spec.rb +5 -5
  215. data/spec/lib/hamster/set/product_spec.rb +2 -2
  216. data/spec/lib/hamster/set/reduce_spec.rb +5 -5
  217. data/spec/lib/hamster/set/{remove_spec.rb → reject_spec.rb} +6 -6
  218. data/spec/lib/hamster/set/reverse_each_spec.rb +1 -1
  219. data/spec/lib/hamster/set/sample_spec.rb +1 -1
  220. data/spec/lib/hamster/set/{filter_spec.rb → select_spec.rb} +11 -11
  221. data/spec/lib/hamster/set/size_spec.rb +1 -1
  222. data/spec/lib/hamster/set/sorting_spec.rb +16 -5
  223. data/spec/lib/hamster/set/subset_spec.rb +2 -2
  224. data/spec/lib/hamster/set/sum_spec.rb +2 -2
  225. data/spec/lib/hamster/set/superset_spec.rb +2 -2
  226. data/spec/lib/hamster/set/to_a_spec.rb +2 -2
  227. data/spec/lib/hamster/set/to_list_spec.rb +2 -2
  228. data/spec/lib/hamster/set/to_set_spec.rb +1 -1
  229. data/spec/lib/hamster/set/union_spec.rb +23 -14
  230. data/spec/lib/hamster/sorted_set/above_spec.rb +11 -11
  231. data/spec/lib/hamster/sorted_set/add_spec.rb +8 -8
  232. data/spec/lib/hamster/sorted_set/at_spec.rb +1 -1
  233. data/spec/lib/hamster/sorted_set/below_spec.rb +11 -11
  234. data/spec/lib/hamster/sorted_set/between_spec.rb +11 -11
  235. data/spec/lib/hamster/sorted_set/clear_spec.rb +11 -2
  236. data/spec/lib/hamster/sorted_set/copying_spec.rb +21 -0
  237. data/spec/lib/hamster/sorted_set/delete_at_spec.rb +4 -4
  238. data/spec/lib/hamster/sorted_set/delete_spec.rb +21 -12
  239. data/spec/lib/hamster/sorted_set/difference_spec.rb +2 -2
  240. data/spec/lib/hamster/sorted_set/disjoint_spec.rb +1 -1
  241. data/spec/lib/hamster/sorted_set/drop_spec.rb +30 -3
  242. data/spec/lib/hamster/sorted_set/drop_while_spec.rb +4 -4
  243. data/spec/lib/hamster/sorted_set/each_spec.rb +16 -18
  244. data/spec/lib/hamster/sorted_set/empty_spec.rb +12 -14
  245. data/spec/lib/hamster/sorted_set/eql_spec.rb +5 -5
  246. data/spec/lib/hamster/sorted_set/exclusion_spec.rb +1 -1
  247. data/spec/lib/hamster/sorted_set/fetch_spec.rb +1 -1
  248. data/spec/lib/hamster/sorted_set/find_index_spec.rb +10 -2
  249. data/spec/lib/hamster/sorted_set/first_spec.rb +10 -12
  250. data/spec/lib/hamster/sorted_set/from_spec.rb +11 -11
  251. data/spec/lib/hamster/sorted_set/group_by_spec.rb +10 -10
  252. data/spec/lib/hamster/sorted_set/include_spec.rb +2 -2
  253. data/spec/lib/hamster/sorted_set/inspect_spec.rb +1 -1
  254. data/spec/lib/hamster/sorted_set/intersect_spec.rb +1 -1
  255. data/spec/lib/hamster/sorted_set/intersection_spec.rb +3 -3
  256. data/spec/lib/hamster/sorted_set/last_spec.rb +1 -1
  257. data/spec/lib/hamster/sorted_set/map_spec.rb +13 -5
  258. data/spec/lib/hamster/sorted_set/marshal_spec.rb +3 -3
  259. data/spec/lib/hamster/sorted_set/maximum_spec.rb +37 -0
  260. data/spec/lib/hamster/sorted_set/minimum_spec.rb +11 -13
  261. data/spec/lib/hamster/sorted_set/new_spec.rb +23 -3
  262. data/spec/lib/hamster/sorted_set/reverse_each_spec.rb +2 -2
  263. data/spec/lib/hamster/sorted_set/{filter_spec.rb → select_spec.rb} +10 -10
  264. data/spec/lib/hamster/sorted_set/size_spec.rb +1 -1
  265. data/spec/lib/hamster/sorted_set/slice_spec.rb +158 -142
  266. data/spec/lib/hamster/sorted_set/sorting_spec.rb +3 -3
  267. data/spec/lib/hamster/sorted_set/subset_spec.rb +2 -2
  268. data/spec/lib/hamster/sorted_set/superset_spec.rb +2 -2
  269. data/spec/lib/hamster/sorted_set/take_spec.rb +32 -3
  270. data/spec/lib/hamster/sorted_set/take_while_spec.rb +4 -4
  271. data/spec/lib/hamster/sorted_set/to_set_spec.rb +1 -1
  272. data/spec/lib/hamster/sorted_set/union_spec.rb +2 -2
  273. data/spec/lib/hamster/sorted_set/up_to_spec.rb +12 -11
  274. data/spec/lib/hamster/sorted_set/values_at_spec.rb +6 -6
  275. data/spec/lib/hamster/vector/add_spec.rb +3 -3
  276. data/spec/lib/hamster/vector/any_spec.rb +1 -1
  277. data/spec/lib/hamster/vector/assoc_spec.rb +11 -1
  278. data/spec/lib/hamster/vector/bsearch_spec.rb +10 -2
  279. data/spec/lib/hamster/vector/clear_spec.rb +3 -3
  280. data/spec/lib/hamster/vector/combination_spec.rb +4 -4
  281. data/spec/lib/hamster/vector/compact_spec.rb +2 -2
  282. data/spec/lib/hamster/vector/compare_spec.rb +3 -3
  283. data/spec/lib/hamster/vector/concat_spec.rb +2 -2
  284. data/spec/lib/hamster/vector/copying_spec.rb +1 -1
  285. data/spec/lib/hamster/vector/delete_at_spec.rb +8 -8
  286. data/spec/lib/hamster/vector/delete_spec.rb +2 -2
  287. data/spec/lib/hamster/vector/drop_spec.rb +10 -3
  288. data/spec/lib/hamster/vector/drop_while_spec.rb +5 -5
  289. data/spec/lib/hamster/vector/each_index_spec.rb +2 -2
  290. data/spec/lib/hamster/vector/each_spec.rb +27 -29
  291. data/spec/lib/hamster/vector/each_with_index_spec.rb +2 -2
  292. data/spec/lib/hamster/vector/empty_spec.rb +11 -13
  293. data/spec/lib/hamster/vector/eql_spec.rb +6 -6
  294. data/spec/lib/hamster/vector/fetch_spec.rb +1 -1
  295. data/spec/lib/hamster/vector/fill_spec.rb +9 -9
  296. data/spec/lib/hamster/vector/first_spec.rb +10 -12
  297. data/spec/lib/hamster/vector/flat_map_spec.rb +51 -0
  298. data/spec/lib/hamster/vector/flatten_spec.rb +15 -0
  299. data/spec/lib/hamster/vector/get_spec.rb +4 -4
  300. data/spec/lib/hamster/vector/group_by_spec.rb +12 -12
  301. data/spec/lib/hamster/vector/include_spec.rb +2 -2
  302. data/spec/lib/hamster/vector/insert_spec.rb +2 -2
  303. data/spec/lib/hamster/vector/inspect_spec.rb +1 -1
  304. data/spec/lib/hamster/vector/join_spec.rb +5 -5
  305. data/spec/lib/hamster/vector/last_spec.rb +1 -1
  306. data/spec/lib/hamster/vector/length_spec.rb +1 -1
  307. data/spec/lib/hamster/vector/ltlt_spec.rb +2 -2
  308. data/spec/lib/hamster/vector/map_spec.rb +5 -5
  309. data/spec/lib/hamster/vector/marshal_spec.rb +2 -2
  310. data/spec/lib/hamster/vector/maximum_spec.rb +20 -22
  311. data/spec/lib/hamster/vector/minimum_spec.rb +20 -22
  312. data/spec/lib/hamster/vector/multiply_spec.rb +4 -4
  313. data/spec/lib/hamster/vector/partition_spec.rb +5 -5
  314. data/spec/lib/hamster/vector/permutation_spec.rb +4 -4
  315. data/spec/lib/hamster/vector/pop_spec.rb +3 -3
  316. data/spec/lib/hamster/vector/product_spec.rb +10 -10
  317. data/spec/lib/hamster/vector/put_spec.rb +175 -0
  318. data/spec/lib/hamster/vector/reduce_spec.rb +5 -57
  319. data/spec/lib/hamster/vector/{remove_spec.rb → reject_spec.rb} +4 -4
  320. data/spec/lib/hamster/vector/repeated_combination_spec.rb +4 -4
  321. data/spec/lib/hamster/vector/repeated_permutation_spec.rb +6 -6
  322. data/spec/lib/hamster/vector/reverse_each_spec.rb +1 -1
  323. data/spec/lib/hamster/vector/reverse_spec.rb +1 -1
  324. data/spec/lib/hamster/vector/rindex_spec.rb +1 -1
  325. data/spec/lib/hamster/vector/rotate_spec.rb +9 -9
  326. data/spec/lib/hamster/vector/sample_spec.rb +1 -1
  327. data/spec/lib/hamster/vector/{filter_spec.rb → select_spec.rb} +8 -8
  328. data/spec/lib/hamster/vector/set_spec.rb +12 -141
  329. data/spec/lib/hamster/vector/shift_spec.rb +3 -3
  330. data/spec/lib/hamster/vector/shuffle_spec.rb +2 -2
  331. data/spec/lib/hamster/vector/slice_spec.rb +137 -137
  332. data/spec/lib/hamster/vector/sorting_spec.rb +5 -5
  333. data/spec/lib/hamster/vector/sum_spec.rb +1 -1
  334. data/spec/lib/hamster/vector/take_spec.rb +17 -3
  335. data/spec/lib/hamster/vector/take_while_spec.rb +4 -4
  336. data/spec/lib/hamster/vector/to_a_spec.rb +1 -1
  337. data/spec/lib/hamster/vector/to_ary_spec.rb +1 -1
  338. data/spec/lib/hamster/vector/to_list_spec.rb +2 -1
  339. data/spec/lib/hamster/vector/to_set_spec.rb +1 -1
  340. data/spec/lib/hamster/vector/uniq_spec.rb +27 -6
  341. data/spec/lib/hamster/vector/unshift_spec.rb +3 -3
  342. data/spec/lib/hamster/vector/values_at_spec.rb +6 -6
  343. data/spec/lib/hamster/vector/zip_spec.rb +2 -2
  344. data/spec/lib/load_spec.rb +42 -0
  345. data/spec/spec_helper.rb +25 -0
  346. metadata +85 -48
  347. data/spec/lib/hamster/deque/head_spec.rb +0 -20
  348. data/spec/lib/hamster/hash/uniq_spec.rb +0 -14
  349. data/spec/lib/hamster/list/elem_index_spec.rb +0 -36
  350. data/spec/lib/hamster/list/elem_indices_spec.rb +0 -31
  351. data/spec/lib/hamster/list/filter_spec.rb +0 -71
  352. data/spec/lib/hamster/list/find_indices_spec.rb +0 -37
  353. data/spec/lib/hamster/set/foreach_spec.rb +0 -40
  354. data/spec/lib/hamster/set/head_spec.rb +0 -31
  355. data/spec/lib/hamster/set/uniq_spec.rb +0 -14
  356. data/spec/lib/hamster/sorted_set/construction_spec.rb +0 -29
  357. data/spec/lib/hamster/vector/exist_spec.rb +0 -70
  358. data/spec/lib/hamster/vector/exists_spec.rb +0 -70
@@ -1,20 +1,19 @@
1
- require "forwardable"
2
1
  require "hamster/set"
3
2
  require "hamster/read_copy_update"
4
3
 
5
4
  module Hamster
6
- def self.mutable_set(*items)
7
- MutableSet.new(set(*items))
8
- end
9
-
5
+ # @api private
10
6
  class MutableSet
11
- extend Forwardable
12
7
  include ReadCopyUpdate
13
8
 
9
+ def self.[](*items)
10
+ MutableSet.new(Set[*items])
11
+ end
12
+
14
13
  def add(item)
15
14
  transform { |set| set.add(item) }
16
15
  end
17
- def_delegator :self, :add, :<<
16
+ alias :<< :add
18
17
 
19
18
  def add?(item)
20
19
  added = false
@@ -1,83 +1,76 @@
1
- require "forwardable"
2
-
3
1
  require "hamster/immutable"
4
2
  require "hamster/undefined"
3
+ require "hamster/enumerable"
5
4
  require "hamster/trie"
6
5
  require "hamster/set"
7
6
  require "hamster/vector"
7
+ require "hamster/associable"
8
8
 
9
9
  module Hamster
10
- def self.hash(pairs = nil, &block)
11
- (pairs.nil? && block.nil?) ? EmptyHash : Hash.new(pairs, &block)
12
- end
13
-
14
- # A `Hamster::Hash` maps from a set of unique keys to corresponding values,
15
- # much like a dictionary maps from words to definitions. Given a key, it can
16
- # efficiently store and retrieve values. Looking up a key given its value is also
17
- # possible, but less efficient. If an existing key is stored again, the new value
18
- # will replace that which was previously stored.
10
+ # A `Hamster::Hash` maps a set of unique keys to corresponding values, much
11
+ # like a dictionary maps from words to definitions. Given a key, it can store
12
+ # and retrieve an associated value in constant time. If an existing key is
13
+ # stored again, the new value will replace the old. It behaves much like
14
+ # Ruby's built-in Hash, which we will call RubyHash for clarity. Like
15
+ # RubyHash, two keys that are `#eql?` to each other and have the same
16
+ # `#hash` are considered identical in a `Hamster::Hash`.
19
17
  #
20
- # It behaves much like Ruby's built-in Hash, which we will call RubyHash
21
- # for clarity. Like RubyHash, `Hamster::Hash` uses `#hash` and `#eql?` to define
22
- # equality between keys. Keys with the same `#hash` code, but which are not `#eql?`
23
- # to each other, can coexist in the same `Hamster::Hash`. To retrieve a previously
24
- # stored value, the key provided must have the same `#hash` code and be `#eql?`
25
- # to the one used for storage.
18
+ # A `Hamster::Hash` can be created in a couple of ways:
26
19
  #
27
- # A `Hamster::Hash` can be created in several ways:
28
- #
29
- # Hamster.hash('Jane Doe' => 10, 'Jim Doe' => 6)
30
20
  # Hamster::Hash.new(font_size: 10, font_family: 'Arial')
31
21
  # Hamster::Hash[first_name: 'John', last_name: 'Smith']
32
22
  #
33
- # If you want to write your own class which inherits from `Hamster::Hash`, you can
34
- # use either of the latter 2 forms of initialization.
35
- #
36
- # Note that any `Enumerable` object which yields 2-element `[key, value]` arrays
37
- # can be used to initialize a `Hamster::Hash`. So this is also possible:
23
+ # Any `Enumerable` object which yields two-element `[key, value]` arrays
24
+ # can be used to initialize a `Hamster::Hash`:
38
25
  #
39
26
  # Hamster::Hash.new([[:first_name, 'John'], [:last_name, 'Smith']])
40
27
  #
41
- # Like RubyHash, key/value pairs can be added using {#store}. Unlike RubyHash,
42
- # a new hash is returned, and the existing one is left unchanged:
28
+ # Key/value pairs can be added using {#put}. A new hash is returned and the
29
+ # existing one is left unchanged:
43
30
  #
44
31
  # hash = Hamster::Hash[a: 100, b: 200]
45
- # hash.store(:c, 500) # => Hamster::Hash[:a => 100, :b => 200, :c => 500]
46
- # hash # => Hamster::Hash[:a => 100, :b => 200]
32
+ # hash.put(:c, 500) # => Hamster::Hash[:a => 100, :b => 200, :c => 500]
33
+ # hash # => Hamster::Hash[:a => 100, :b => 200]
47
34
  #
48
- # You also use {#put}. The difference is that {#put} can optionally take a block which
49
- # is used to calculate the value to be stored:
35
+ # {#put} can also take a block, which is used to calculate the value to be
36
+ # stored.
50
37
  #
51
- # hash.put(:a) { hash[:b] + 100 } # => Hamster::Hash[:a => 300, :b => 200]
38
+ # hash.put(:a) { |current| current + 200 } # => Hamster::Hash[:a => 300, :b => 200]
52
39
  #
53
- # Since it is immutable, all methods which you might expect to "modify" a `Hamster::Hash`
54
- # actually return a new hash and leave the existing one unchanged. This means that the
55
- # `hash[key] = value` syntax used with RubyHashes *cannot* be used with `Hamster::Hash`.
40
+ # Since it is immutable, all methods which you might expect to "modify" a
41
+ # `Hamster::Hash` actually return a new hash and leave the existing one
42
+ # unchanged. This means that the `hash[key] = value` syntax from RubyHash
43
+ # *cannot* be used with `Hamster::Hash`.
56
44
  #
57
- # While a `Hamster::Hash` can iterate over its keys (or values), it does not
58
- # guarantee any specific iteration order (unlike RubyHash). Likewise, methods like
59
- # {#flatten} do not guarantee which order the returned key/value pairs will appear
60
- # in.
45
+ # Nested data structures can easily be updated using {#update_in}:
61
46
  #
62
- # Like RubyHash, a `Hamster::Hash` can have a default block which is used when
63
- # looking up a key which does not exist in the hash. Unlike RubyHash, the default
64
- # block will only be passed the missing key, not the hash itself:
47
+ # hash = Hamster::Hash["a" => Hamster::Vector[Hamster::Hash["c" => 42]]]
48
+ # hash.update_in("a", 0, "c") { |value| value + 5 }
49
+ # # => Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 47]]]
65
50
  #
66
- # hash = Hamster::Hash.new { |n| n * 10 }
67
- # hash[5] # => 50
51
+ # While a `Hamster::Hash` can iterate over its keys or values, it does not
52
+ # guarantee any specific iteration order (unlike RubyHash). Methods like
53
+ # {#flatten} do not guarantee the order of returned key/value pairs.
68
54
  #
69
- # A default block can only be set when creating a `Hamster::Hash` with `Hamster::Hash.new` or
70
- # {Hamster.hash Hamster.hash}, not with {Hamster::Hash.[] Hamster::Hash[]}. Default blocks
71
- # do not survive marshalling and unmarshalling.
55
+ # Like RubyHash, a `Hamster::Hash` can have a default block which is used
56
+ # when looking up a key that does not exist. Unlike RubyHash, the default
57
+ # block will only be passed the missing key, without the hash itself:
72
58
  #
59
+ # hash = Hamster::Hash.new { |missing_key| missing_key * 10 }
60
+ # hash[5] # => 50
73
61
  class Hash
74
- extend Forwardable
75
62
  include Immutable
76
63
  include Enumerable
64
+ include Associable
77
65
 
78
66
  class << self
79
67
  # Create a new `Hash` populated with the given key/value pairs.
80
68
  #
69
+ # @example
70
+ # Hamster::Hash["A" => 1, "B" => 2] # => Hamster::Hash["A" => 1, "B" => 2]
71
+ # Hamster::Hash[["A", 1], ["B", 2]] # => Hamster::Hash["A" => 1, "B" => 2]
72
+ #
73
+ # @param pairs [::Enumerable] initial content of hash. An empty hash is returned if not provided.
81
74
  # @return [Hash]
82
75
  def [](pairs = nil)
83
76
  (pairs.nil? || pairs.empty?) ? empty : new(pairs)
@@ -104,6 +97,9 @@ module Hamster
104
97
  end
105
98
  end
106
99
 
100
+ # @param pairs [::Enumerable] initial content of hash. An empty hash is returned if not provided.
101
+ # @yield [key] Optional _default block_ to be stored and used to calculate the default value of a missing key. It will not be yielded during this method. It will not be preserved when marshalling.
102
+ # @yieldparam key Key that was not present in the hash.
107
103
  def initialize(pairs = nil, &block)
108
104
  @trie = pairs ? Trie[pairs] : EmptyTrie
109
105
  @default = block
@@ -118,11 +114,14 @@ module Hamster
118
114
 
119
115
  # Return the number of key/value pairs in this `Hash`.
120
116
  #
117
+ # @example
118
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3].size # => 3
119
+ #
121
120
  # @return [Integer]
122
121
  def size
123
122
  @trie.size
124
123
  end
125
- def_delegator :self, :size, :length
124
+ alias :length :size
126
125
 
127
126
  # Return `true` if this `Hash` contains no key/value pairs.
128
127
  #
@@ -130,34 +129,50 @@ module Hamster
130
129
  def empty?
131
130
  @trie.empty?
132
131
  end
133
- def_delegator :self, :empty?, :null?
134
132
 
135
133
  # Return `true` if the given key object is present in this `Hash`. More precisely,
136
134
  # return `true` if a key with the same `#hash` code, and which is also `#eql?`
137
135
  # to the given key object is present.
138
136
  #
137
+ # @example
138
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3].key?("B") # => true
139
+ #
139
140
  # @param key [Object] The key to check for
140
141
  # @return [Boolean]
141
142
  def key?(key)
142
143
  @trie.key?(key)
143
144
  end
144
- def_delegator :self, :key?, :has_key?
145
- def_delegator :self, :key?, :include?
146
- def_delegator :self, :key?, :member?
145
+ alias :has_key? :key?
146
+ alias :include? :key?
147
+ alias :member? :key?
147
148
 
148
149
  # Return `true` if this `Hash` has one or more keys which map to the provided value.
149
150
  #
151
+ # @example
152
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3].value?(2) # => true
153
+ #
150
154
  # @param value [Object] The value to check for
151
155
  # @return [Boolean]
152
156
  def value?(value)
153
157
  each { |k,v| return true if value == v }
154
158
  false
155
159
  end
156
- def_delegator :self, :value?, :has_value?
160
+ alias :has_value? :value?
157
161
 
158
162
  # Retrieve the value corresponding to the provided key object. If not found, and
159
163
  # this `Hash` has a default block, the default block is called to provide the
160
- # value.
164
+ # value. Otherwise, return `nil`.
165
+ #
166
+ # @example
167
+ # h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
168
+ # h["B"] # => 2
169
+ # h.get("B") # => 2
170
+ # h.get("Elephant") # => nil
171
+ #
172
+ # # Hamster Hash with a default proc:
173
+ # h = Hamster::Hash.new("A" => 1, "B" => 2, "C" => 3) { |key| key.size }
174
+ # h.get("B") # => 2
175
+ # h.get("Elephant") # => 8
161
176
  #
162
177
  # @param key [Object] The key to look up
163
178
  # @return [Object]
@@ -169,7 +184,7 @@ module Hamster
169
184
  @default.call(key)
170
185
  end
171
186
  end
172
- def_delegator :self, :get, :[]
187
+ alias :[] :get
173
188
 
174
189
  # Retrieve the value corresponding to the given key object, or use the provided
175
190
  # default value or block, or otherwise raise a `KeyError`.
@@ -190,6 +205,19 @@ module Hamster
190
205
  # @param key [Object] The key to look up
191
206
  # @param default [Object] Object to return if the key is not found
192
207
  #
208
+ # @example
209
+ # h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
210
+ # h.fetch("B") # => 2
211
+ # h.fetch("Elephant") # => KeyError: key not found: "Elephant"
212
+ #
213
+ # # with a default value:
214
+ # h.fetch("B", 99) # => 2
215
+ # h.fetch("Elephant", 99) # => 99
216
+ #
217
+ # # with a block:
218
+ # h.fetch("B") { |key| key.size } # => 2
219
+ # h.fetch("Elephant") { |key| key.size } # => 8
220
+ #
193
221
  # @return [Object]
194
222
  def fetch(key, default = Undefined)
195
223
  entry = @trie.get(key)
@@ -213,36 +241,70 @@ module Hamster
213
241
  # returns will replace the existing value. This is useful for "transforming"
214
242
  # the value associated with a certain key.
215
243
  #
216
- # Avoid mutating objects which are used as keys. `String`s are an exception --
244
+ # Avoid mutating objects which are used as keys. `String`s are an exception:
217
245
  # unfrozen `String`s which are used as keys are internally duplicated and
218
- # frozen.
246
+ # frozen. This matches RubyHash's behaviour.
247
+ #
248
+ # @example
249
+ # h = Hamster::Hash["A" => 1, "B" => 2]
250
+ # h.put("C", 3)
251
+ # # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
252
+ # h.put("B") { |value| value * 10 }
253
+ # # => Hamster::Hash["A" => 1, "B" => 20]
219
254
  #
220
255
  # @param key [Object] The key to store
221
256
  # @param value [Object] The value to associate it with
222
- # @yield [value] The previously stored value
257
+ # @yield [value] The previously stored value, or `nil` if none.
223
258
  # @yieldreturn [Object] The new value to store
224
259
  # @return [Hash]
225
260
  def put(key, value = yield(get(key)))
226
- self.class.alloc(@trie.put(key, value), @default)
261
+ new_trie = @trie.put(key, value)
262
+ if new_trie.equal?(@trie)
263
+ self
264
+ else
265
+ self.class.alloc(new_trie, @default)
266
+ end
227
267
  end
228
268
 
229
- # Return a new `Hash` with the existing key/value associations, plus an association
230
- # between the provided key and value. If an equivalent key is already present, its
231
- # associated value will be replaced with the provided one.
269
+ # Return a new `Hash` with a deeply nested value modified to the result of
270
+ # the given code block. When traversing the nested `Hash`es and `Vector`s,
271
+ # non-existing keys are created with empty `Hash` values.
232
272
  #
233
- # Avoid mutating objects which are used as keys. `String`s are an exception --
234
- # unfrozen `String`s which are used as keys are internally duplicated and
235
- # frozen.
273
+ # The code block receives the existing value of the deeply nested key (or
274
+ # `nil` if it doesn't exist). This is useful for "transforming" the value
275
+ # associated with a certain key.
276
+ #
277
+ # Note that the original `Hash` and sub-`Hash`es and sub-`Vector`s are left
278
+ # unmodified; new data structure copies are created along the path wherever
279
+ # needed.
280
+ #
281
+ # @example
282
+ # hash = Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 42]]]
283
+ # hash.update_in("a", "b", "c") { |value| value + 5 }
284
+ # # => Hamster::Hash["a" => Hamster::Hash["b" => Hamster::Hash["c" => 47]]]
285
+ #
286
+ # @param key_path [::Array<Object>] List of keys which form the path to the key to be modified
287
+ # @yield [value] The previously stored value
288
+ # @yieldreturn [Object] The new value to store
289
+ # @return [Hash]
290
+
291
+ # An alias for {#put} to match RubyHash's API. Does not support {#put}'s
292
+ # block form.
236
293
  #
294
+ # @see #put
237
295
  # @param key [Object] The key to store
238
296
  # @param value [Object] The value to associate it with
239
297
  # @return [Hash]
240
298
  def store(key, value)
241
- self.class.alloc(@trie.put(key, value), @default)
299
+ put(key, value)
242
300
  end
243
301
 
244
- # Return a new `Hash` with the association for `key` removed. If `key` is not
245
- # present, return `self`.
302
+ # Return a new `Hash` with `key` removed. If `key` is not present, return
303
+ # `self`.
304
+ #
305
+ # @example
306
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3].delete("B")
307
+ # # => Hamster::Hash["A" => 1, "C" => 3]
246
308
  #
247
309
  # @param key [Object] The key to remove
248
310
  # @return [Hash]
@@ -251,20 +313,38 @@ module Hamster
251
313
  end
252
314
 
253
315
  # Call the block once for each key/value pair in this `Hash`, passing the key/value
254
- # pair as parameters. No specific iteration order is guaranteed (but the order will
255
- # be stable for any particular `Hash`.)
316
+ # pair as parameters. No specific iteration order is guaranteed, though the order will
317
+ # be stable for any particular `Hash`.
256
318
  #
319
+ # @example
320
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each { |k, v| puts "k=#{k} v=#{v}" }
321
+ #
322
+ # k=A v=1
323
+ # k=C v=3
324
+ # k=B v=2
325
+ # # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
326
+ #
327
+ # @yield [key, value] Once for each key/value pair.
257
328
  # @return [self]
258
329
  def each(&block)
259
330
  return to_enum if not block_given?
260
331
  @trie.each(&block)
261
332
  self
262
333
  end
263
- def_delegator :self, :each, :each_pair
334
+ alias :each_pair :each
264
335
 
265
336
  # Call the block once for each key/value pair in this `Hash`, passing the key/value
266
337
  # pair as parameters. Iteration order will be the opposite of {#each}.
267
338
  #
339
+ # @example
340
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3].reverse_each { |k, v| puts "k=#{k} v=#{v}" }
341
+ #
342
+ # k=B v=2
343
+ # k=C v=3
344
+ # k=A v=1
345
+ # # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
346
+ #
347
+ # @yield [key, value] Once for each key/value pair.
268
348
  # @return [self]
269
349
  def reverse_each(&block)
270
350
  return enum_for(:reverse_each) if not block_given?
@@ -273,8 +353,17 @@ module Hamster
273
353
  end
274
354
 
275
355
  # Call the block once for each key/value pair in this `Hash`, passing the key as a
276
- # parameter.
356
+ # parameter. Ordering guarantees are the same as {#each}.
277
357
  #
358
+ # @example
359
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each_key { |k| puts "k=#{k}" }
360
+ #
361
+ # k=A
362
+ # k=C
363
+ # k=B
364
+ # # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
365
+ #
366
+ # @yield [key] Once for each key/value pair.
278
367
  # @return [self]
279
368
  def each_key
280
369
  return enum_for(:each_key) if not block_given?
@@ -283,8 +372,17 @@ module Hamster
283
372
  end
284
373
 
285
374
  # Call the block once for each key/value pair in this `Hash`, passing the value as a
286
- # parameter.
375
+ # parameter. Ordering guarantees are the same as {#each}.
376
+ #
377
+ # @example
378
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3].each_value { |v| puts "v=#{v}" }
287
379
  #
380
+ # v=1
381
+ # v=3
382
+ # v=2
383
+ # # => Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
384
+ #
385
+ # @yield [value] Once for each key/value pair.
288
386
  # @return [self]
289
387
  def each_value
290
388
  return enum_for(:each_value) if not block_given?
@@ -296,48 +394,72 @@ module Hamster
296
394
  # pair as parameters. The block should return a `[key, value]` array each time.
297
395
  # All the returned `[key, value]` arrays will be gathered into a new `Hash`.
298
396
  #
397
+ # @example
398
+ # h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
399
+ # h.map { |k, v| ["new-#{k}", v * v] }
400
+ # # => Hash["new-C" => 9, "new-B" => 4, "new-A" => 1]
401
+ #
402
+ # @yield [key, value] Once for each key/value pair.
299
403
  # @return [Hash]
300
404
  def map
301
405
  return enum_for(:map) unless block_given?
302
406
  return self if empty?
303
407
  self.class.new(super, &@default)
304
408
  end
305
- def_delegator :self, :map, :collect
306
-
307
- def_delegator :self, :reduce, :foldr
409
+ alias :collect :map
308
410
 
309
411
  # Return a new `Hash` with all the key/value pairs for which the block returns true.
310
412
  #
413
+ # @example
414
+ # h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
415
+ # h.select { |k, v| v >= 2 }
416
+ # # => Hamster::Hash["B" => 2, "C" => 3]
417
+ #
418
+ # @yield [key, value] Once for each key/value pair.
419
+ # @yieldreturn Truthy if this pair should be present in the new `Hash`.
311
420
  # @return [Hash]
312
- def filter(&block)
313
- return enum_for(:filter) unless block_given?
314
- derive_new_hash(@trie.filter(&block))
421
+ def select(&block)
422
+ return enum_for(:select) unless block_given?
423
+ derive_new_hash(@trie.select(&block))
315
424
  end
425
+ alias :find_all :select
426
+ alias :keep_if :select
316
427
 
317
428
  # Yield `[key, value]` pairs until one is found for which the block returns true.
318
429
  # Return that `[key, value]` pair. If the block never returns true, return `nil`.
319
430
  #
431
+ # @example
432
+ # h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
433
+ # h.find { |k, v| v.even? }
434
+ # # => ["B", 2]
435
+ #
320
436
  # @return [Array]
437
+ # @yield [key, value] At most once for each key/value pair, until the block returns `true`.
438
+ # @yieldreturn Truthy to halt iteration and return the yielded key/value pair.
321
439
  def find
322
440
  return enum_for(:find) unless block_given?
323
441
  each { |entry| return entry if yield entry }
324
442
  nil
325
443
  end
326
- def_delegator :self, :find, :detect
327
-
328
- def_delegator :self, :max, :maximum
329
- def_delegator :self, :min, :minimum
444
+ alias :detect :find
330
445
 
331
446
  # Return a new `Hash` containing all the key/value pairs from this `Hash` and
332
447
  # `other`. If no block is provided, the value for entries with colliding keys
333
- # will be that from `other`. Otherwie, the value for each duplicate key is
334
- # determined by called the block with the key, its value in this `Hash`, and
335
- # its value in `other`.
448
+ # will be that from `other`. Otherwise, the value for each duplicate key is
449
+ # determined by calling the block.
336
450
  #
337
451
  # `other` can be a `Hamster::Hash`, a built-in Ruby `Hash`, or any `Enumerable`
338
452
  # object which yields `[key, value]` pairs.
339
453
  #
340
- # @param other [Enumerable] The collection to merge with
454
+ # @example
455
+ # h1 = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
456
+ # h2 = Hamster::Hash["C" => 70, "D" => 80]
457
+ # h1.merge(h2)
458
+ # # => Hamster::Hash["C" => 70, "A" => 1, "D" => 80, "B" => 2]
459
+ # h1.merge(h2) { |key, v1, v2| v1 + v2 }
460
+ # # => Hamster::Hash["C" => 73, "A" => 1, "D" => 80, "B" => 2]
461
+ #
462
+ # @param other [::Enumerable] The collection to merge with
341
463
  # @yieldparam key [Object] The key which was present in both collections
342
464
  # @yieldparam my_value [Object] The associated value from this `Hash`
343
465
  # @yieldparam other_value [Object] The associated value from the other collection
@@ -353,17 +475,38 @@ module Hamster
353
475
  end
354
476
  end
355
477
  else
356
- other.reduce(@trie) { |trie, (key, value)| trie.put(key, value) }
478
+ @trie.bulk_put(other)
357
479
  end
358
480
 
359
481
  derive_new_hash(trie)
360
482
  end
361
- def_delegator :self, :merge, :+
362
483
 
363
- # Return a {Vector} which contains all the `[key, value]` pairs in this `Hash`
364
- # as 2-element Arrays, either in their natural sorted order as determined by
365
- # `#<=>`, or if an optional block is supplied, by using the block as a comparator.
366
- # See `Enumerable#sort`.
484
+ # Retrieve the value corresponding to the given key object, or use the provided
485
+ # default value or block, or otherwise raise a `KeyError`.
486
+ #
487
+ # @overload fetch(key)
488
+ # Retrieve the value corresponding to the given key, or raise a `KeyError`
489
+ # if it is not found.
490
+ # @param key [Object] The key to look up
491
+ # @overload fetch(key) { |key| ... }
492
+
493
+ # Return a sorted {Vector} which contains all the `[key, value]` pairs in
494
+ # this `Hash` as two-element `Array`s.
495
+ #
496
+ # @overload sort
497
+ # Uses `#<=>` to determine sorted order.
498
+ # @overload sort { |(k1, v1), (k2, v2)| ... }
499
+ # Uses the block as a comparator to determine sorted order.
500
+ #
501
+ # @example
502
+ # h = Hamster::Hash["Dog" => 1, "Elephant" => 2, "Lion" => 3]
503
+ # h.sort { |(k1, v1), (k2, v2)| k1.size <=> k2.size }
504
+ # # => Hamster::Vector[["Dog", 1], ["Lion", 3], ["Elephant", 2]]
505
+ # @yield [(k1, v1), (k2, v2)] Any number of times with different pairs of key/value associations.
506
+ # @yieldreturn [Integer] Negative if the first pair should be sorted
507
+ # lower, positive if the latter pair, or 0 if equal.
508
+ #
509
+ # @see ::Enumerable#sort
367
510
  #
368
511
  # @return [Vector]
369
512
  def sort
@@ -371,11 +514,19 @@ module Hamster
371
514
  end
372
515
 
373
516
  # Return a {Vector} which contains all the `[key, value]` pairs in this `Hash`
374
- # as 2-element Arrays. The order which the pairs will appear in is determined by
517
+ # as two-element Arrays. The order which the pairs will appear in is determined by
375
518
  # passing each pair to the code block to obtain a sort key object, and comparing
376
519
  # the sort keys using `#<=>`.
377
- # See `Enumerable#sort_by`.
378
520
  #
521
+ # @see ::Enumerable#sort_by
522
+ #
523
+ # @example
524
+ # h = Hamster::Hash["Dog" => 1, "Elephant" => 2, "Lion" => 3]
525
+ # h.sort_by { |key, value| key.size }
526
+ # # => Hamster::Vector[["Dog", 1], ["Lion", 3], ["Elephant", 2]]
527
+ #
528
+ # @yield [key, value] Once for each key/value pair.
529
+ # @yieldreturn a sort key object for the yielded pair.
379
530
  # @return [Vector]
380
531
  def sort_by
381
532
  Vector.new(super)
@@ -383,6 +534,10 @@ module Hamster
383
534
 
384
535
  # Return a new `Hash` with the associations for all of the given `keys` removed.
385
536
  #
537
+ # @example
538
+ # h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
539
+ # h.except("A", "C") # => Hamster::Hash["B" => 2]
540
+ #
386
541
  # @param keys [Array] The keys to remove
387
542
  # @return [Hash]
388
543
  def except(*keys)
@@ -390,10 +545,12 @@ module Hamster
390
545
  end
391
546
 
392
547
  # Return a new `Hash` with only the associations for the `wanted` keys retained.
393
- # If any of the `wanted` keys are not present in this `Hash`, they will not be present
394
- # in the returned `Hash` either.
395
548
  #
396
- # @param wanted [Array] The keys to retain
549
+ # @example
550
+ # h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
551
+ # h.slice("B", "C") # => Hamster::Hash["B" => 2, "C" => 3]
552
+ #
553
+ # @param wanted [::Enumerable] The keys to retain
397
554
  # @return [Hash]
398
555
  def slice(*wanted)
399
556
  trie = Trie.new(0)
@@ -404,6 +561,10 @@ module Hamster
404
561
  # Return a {Vector} of the values which correspond to the `wanted` keys.
405
562
  # If any of the `wanted` keys are not present in this `Hash`, they will be skipped.
406
563
  #
564
+ # @example
565
+ # h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
566
+ # h.values_at("B", "A", "D") # => Hamster::Vector[2, 1]
567
+ #
407
568
  # @param wanted [Array] The keys to retrieve
408
569
  # @return [Vector]
409
570
  def values_at(*wanted)
@@ -412,7 +573,11 @@ module Hamster
412
573
  Vector.new(array.freeze)
413
574
  end
414
575
 
415
- # Return a new {Set} populated with the keys from this `Hash`.
576
+ # Return a new {Set} containing the keys from this `Hash`.
577
+ #
578
+ # @example
579
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].keys
580
+ # # => Hamster::Set["D", "C", "B", "A"]
416
581
  #
417
582
  # @return [Set]
418
583
  def keys
@@ -421,14 +586,23 @@ module Hamster
421
586
 
422
587
  # Return a new {Vector} populated with the values from this `Hash`.
423
588
  #
589
+ # @example
590
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].values
591
+ # # => Hamster::Vector[2, 3, 2, 1]
592
+ #
424
593
  # @return [Vector]
425
594
  def values
426
595
  Vector.new(each_value.to_a.freeze)
427
596
  end
428
597
 
429
- # Return a new `Hash` created by using our keys as values, and values as keys.
598
+ # Return a new `Hash` created by using keys as values and values as keys.
430
599
  # If there are multiple values which are equivalent (as determined by `#hash` and
431
- # `#eql?`), only one out of each group of equivalent values will be retained.
600
+ # `#eql?`), only one out of each group of equivalent values will be
601
+ # retained. Which one specifically is undefined.
602
+ #
603
+ # @example
604
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3, "D" => 2].invert
605
+ # # => Hamster::Hash[1 => "A", 3 => "C", 2 => "B"]
432
606
  #
433
607
  # @return [Hash]
434
608
  def invert
@@ -447,6 +621,13 @@ module Hamster
447
621
  # As a special case, if `level` is 0, each `[key, value]` pair will be a
448
622
  # separate element in the returned {Vector}.
449
623
  #
624
+ # @example
625
+ # h = Hamster::Hash["A" => 1, "B" => [2, 3, 4]]
626
+ # h.flatten
627
+ # # => Hamster::Vector["A", 1, "B", [2, 3, 4]]
628
+ # h.flatten(2)
629
+ # # => Hamster::Vector["A", 1, "B", 2, 3, 4]
630
+ #
450
631
  # @param level [Integer] The number of times to recursively flatten the `[key, value]` pairs in this `Hash`.
451
632
  # @return [Vector]
452
633
  def flatten(level = 1)
@@ -461,6 +642,9 @@ module Hamster
461
642
  # When a matching key is found, return the `[key, value]` pair as an array.
462
643
  # Return `nil` if no match is found.
463
644
  #
645
+ # @example
646
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3].assoc("B") # => ["B", 2]
647
+ #
464
648
  # @param obj [Object] The key to search for (using #==)
465
649
  # @return [Array]
466
650
  def assoc(obj)
@@ -472,6 +656,9 @@ module Hamster
472
656
  # When a matching value is found, return the `[key, value]` pair as an array.
473
657
  # Return `nil` if no match is found.
474
658
  #
659
+ # @example
660
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3].rassoc(2) # => ["B", 2]
661
+ #
475
662
  # @param obj [Object] The value to search for (using #==)
476
663
  # @return [Array]
477
664
  def rassoc(obj)
@@ -483,6 +670,9 @@ module Hamster
483
670
  # When a matching value is found, return its associated key object.
484
671
  # Return `nil` if no match is found.
485
672
  #
673
+ # @example
674
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3].key(2) # => "B"
675
+ #
486
676
  # @param value [Object] The value to search for (using #==)
487
677
  # @return [Object]
488
678
  def key(value)
@@ -493,6 +683,10 @@ module Hamster
493
683
  # Return a randomly chosen `[key, value]` pair from this `Hash`. If the hash is empty,
494
684
  # return `nil`.
495
685
  #
686
+ # @example
687
+ # Hamster::Hash["A" => 1, "B" => 2, "C" => 3].sample
688
+ # # => ["C", 3]
689
+ #
496
690
  # @return [Array]
497
691
  def sample
498
692
  @trie.at(rand(size))
@@ -537,14 +731,10 @@ module Hamster
537
731
  end
538
732
  end
539
733
 
540
- def_delegator :self, :dup, :uniq
541
- def_delegator :self, :dup, :nub
542
- def_delegator :self, :dup, :remove_duplicates
543
-
544
734
  # Return the contents of this `Hash` as a programmer-readable `String`. If all the
545
735
  # keys and values are serializable as Ruby literal strings, the returned string can
546
- # be passed to `eval` to reconstitute an equivalent `Hash`. However, the default
547
- # block (if there is one) will be lost when doing this.
736
+ # be passed to `eval` to reconstitute an equivalent `Hash`. The default
737
+ # block (if there is one) will be lost when doing this, however.
548
738
  #
549
739
  # @return [String]
550
740
  def inspect
@@ -590,7 +780,7 @@ module Hamster
590
780
  end
591
781
  output
592
782
  end
593
- def_delegator :self, :to_hash, :to_h
783
+ alias :to_h :to_hash
594
784
 
595
785
  # @return [::Hash]
596
786
  # @private
@@ -623,9 +813,10 @@ module Hamster
623
813
  end
624
814
  end
625
815
 
626
- # The canonical empty `Hash`. Returned by `Hamster.hash` and `Hash[]` when
816
+ # The canonical empty `Hash`. Returned by `Hash[]` when
627
817
  # invoked with no arguments; also returned by `Hash.empty`. Prefer using this
628
818
  # one rather than creating many empty hashes using `Hash.new`.
629
819
  #
820
+ # @private
630
821
  EmptyHash = Hamster::Hash.empty
631
822
  end