facets 2.6.0 → 2.7.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 (321) hide show
  1. data/HISTORY.rdoc +331 -35
  2. data/MANIFEST +685 -826
  3. data/{doc/guide/notes.rd → NOTES} +0 -0
  4. data/README.rdoc +73 -25
  5. data/Rakefile +245 -2
  6. data/TODO +5 -0
  7. data/demo/hook.rd +47 -0
  8. data/demo/scenario_require.rd +9 -0
  9. data/doc/README.more +24 -6
  10. data/doc/manual/about.rb +47 -0
  11. data/doc/manual/annotations.rdoc +60 -0
  12. data/doc/manual/associations.rdoc +55 -0
  13. data/doc/manual/blockups.rdoc +101 -0
  14. data/doc/manual/capsule.rdoc +34 -0
  15. data/doc/manual/command.rdoc +177 -0
  16. data/doc/manual/core.rdoc +37 -0
  17. data/doc/manual/faq.rdoc +32 -0
  18. data/doc/manual/typecast.html +112 -0
  19. data/lib/core/facets.rb +359 -11
  20. data/lib/core/facets/array/combination.rb +3 -3
  21. data/lib/core/facets/array/index.rb +4 -1
  22. data/lib/core/facets/array/permutation.rb +2 -2
  23. data/lib/core/facets/array/product.rb +1 -1
  24. data/lib/core/facets/binding/eval.rb +1 -1
  25. data/lib/core/facets/denumerable.rb +76 -0
  26. data/lib/core/facets/duplicable.rb +34 -0
  27. data/lib/core/facets/enumerable/count.rb +10 -4
  28. data/lib/core/facets/enumerable/defer.rb +77 -0
  29. data/lib/core/facets/enumerable/each_by.rb +1 -1
  30. data/lib/core/facets/enumerable/every.rb +35 -0
  31. data/lib/{more/facets/elementwise.rb → core/facets/enumerable/ewise.rb} +0 -0
  32. data/lib/core/facets/enumerable/filter.rb +25 -0
  33. data/lib/core/facets/enumerable/group_by.rb +1 -1
  34. data/lib/core/facets/enumerable/none.rb +3 -2
  35. data/lib/core/facets/enumerable/one.rb +3 -2
  36. data/lib/core/facets/enumerable/per.rb +61 -0
  37. data/lib/core/facets/exception/raised.rb +14 -0
  38. data/lib/core/facets/integer/odd.rb +5 -1
  39. data/lib/core/facets/kernel/__dir__.rb +13 -3
  40. data/lib/core/facets/kernel/__here__.rb +14 -0
  41. data/lib/core/facets/kernel/__method__.rb +9 -3
  42. data/lib/core/facets/kernel/ask.rb +1 -0
  43. data/lib/core/facets/kernel/equate.rb +13 -0
  44. data/lib/core/facets/kernel/extension.rb +9 -0
  45. data/lib/core/facets/kernel/identical.rb +4 -0
  46. data/lib/core/facets/kernel/instance_exec.rb +2 -1
  47. data/lib/core/facets/kernel/method.rb +49 -0
  48. data/lib/core/facets/kernel/object_send.rb +2 -2
  49. data/lib/core/facets/kernel/{state.rb → object_state.rb} +23 -12
  50. data/lib/core/facets/kernel/require_all.rb +6 -1
  51. data/lib/core/facets/kernel/require_local.rb +8 -1
  52. data/lib/core/facets/kernel/require_relative.rb +52 -0
  53. data/lib/core/facets/kernel/source_location.rb +13 -0
  54. data/lib/core/facets/kernel/tap.rb +13 -6
  55. data/lib/core/facets/module/attr_setter.rb +57 -0
  56. data/lib/core/facets/module/instance_method.rb +24 -0
  57. data/lib/core/facets/module/module_load.rb +60 -44
  58. data/lib/core/facets/module/module_require.rb +1 -0
  59. data/lib/core/facets/nilclass/to_f.rb +1 -1
  60. data/lib/core/facets/objectspace/op_fetch.rb +3 -0
  61. data/lib/core/facets/proc/curry.rb +4 -3
  62. data/lib/core/facets/string/bytes.rb +10 -4
  63. data/lib/core/facets/string/camelcase.rb +6 -5
  64. data/lib/core/facets/string/chars.rb +5 -1
  65. data/lib/core/facets/string/each_char.rb +1 -1
  66. data/lib/core/facets/string/each_word.rb +1 -1
  67. data/lib/core/facets/string/lines.rb +11 -4
  68. data/lib/core/facets/string/start_with.rb +9 -2
  69. data/lib/core/facets/string/unfold.rb +27 -0
  70. data/lib/core/facets/symbol/succ.rb +3 -3
  71. data/lib/core/facets/symbol/thrown.rb +20 -0
  72. data/lib/core/facets/symbol/to_proc.rb +3 -2
  73. data/lib/core/facets/time/to_time.rb +1 -1
  74. data/lib/core/facets/to_hash.rb +41 -100
  75. data/lib/core/facets/unboundmethod/name.rb +20 -23
  76. data/lib/more/facets/ansicode.rb +1 -10
  77. data/lib/more/facets/autoarray.rb +3 -31
  78. data/lib/more/facets/basicobject.rb +73 -0
  79. data/lib/more/facets/blankslate.rb +2 -66
  80. data/lib/{lore → more}/facets/cgi.rb +0 -0
  81. data/lib/more/facets/class_extend.rb +1 -0
  82. data/lib/{lore → more}/facets/continuation.rb +0 -0
  83. data/lib/{lore → more}/facets/date.rb +3 -3
  84. data/lib/more/facets/enumargs.rb +192 -0
  85. data/lib/more/facets/enumerablepass.rb +2 -216
  86. data/lib/more/facets/enumerator.rb +62 -0
  87. data/lib/more/facets/{equatable.rb → equitable.rb} +11 -11
  88. data/lib/more/facets/expirable.rb +13 -41
  89. data/lib/{lore → more}/facets/fileutils.rb +0 -0
  90. data/lib/{lore → more}/facets/fileutils/head.rb +0 -0
  91. data/lib/{lore → more}/facets/fileutils/safe_ln.rb +0 -0
  92. data/lib/{lore → more}/facets/fileutils/slice.rb +0 -0
  93. data/lib/{lore → more}/facets/fileutils/tail.rb +0 -0
  94. data/lib/{lore → more}/facets/fileutils/wc.rb +0 -0
  95. data/lib/{lore → more}/facets/fileutils/whereis.rb +0 -0
  96. data/lib/{lore → more}/facets/fileutils/which.rb +0 -0
  97. data/lib/{lore → more}/facets/getoptlong.rb +0 -0
  98. data/lib/more/facets/hook.rb +2 -29
  99. data/lib/more/facets/inheritor.rb +2 -2
  100. data/lib/more/facets/instance_eval.rb +50 -0
  101. data/lib/more/facets/instance_function.rb +78 -0
  102. data/lib/more/facets/main.rb +20 -15
  103. data/lib/more/facets/memoize.rb +1 -113
  104. data/lib/more/facets/module/attr.rb +83 -0
  105. data/lib/more/facets/module/attr_tester.rb +44 -0
  106. data/lib/more/facets/module/attr_toggler.rb +59 -0
  107. data/lib/more/facets/module/attr_validator.rb +34 -0
  108. data/lib/more/facets/{class_extension.rb → module/class_extend.rb} +21 -13
  109. data/lib/more/facets/once.rb +59 -0
  110. data/lib/more/facets/openmodule.rb +1 -0
  111. data/lib/more/facets/orderedhash.rb +1 -33
  112. data/lib/{lore → more}/facets/ostruct.rb +0 -0
  113. data/lib/more/facets/ostructable.rb +1 -4
  114. data/lib/more/facets/partial.rb +18 -16
  115. data/lib/{lore → more}/facets/pathname.rb +0 -0
  116. data/lib/more/facets/preinitialize.rb +157 -0
  117. data/lib/{lore → more}/facets/rbconfig.rb +0 -0
  118. data/lib/more/facets/recorder.rb +1 -2
  119. data/lib/{lore → more}/facets/set.rb +0 -0
  120. data/lib/{lore → more}/facets/shellwords.rb +0 -0
  121. data/lib/{lore → more}/facets/uri.rb +0 -0
  122. data/lib/{lore → more}/facets/yaml.rb +0 -0
  123. data/lib/{lore → more}/facets/zlib.rb +0 -0
  124. data/meta/loadpath +0 -1
  125. data/meta/sitemap +4 -0
  126. data/meta/version +1 -1
  127. data/test/core/enumerable/test_count.rb +1 -1
  128. data/test/{more/test_filter.rb → core/enumerable/test_defer.rb} +24 -22
  129. data/test/{more/test_elementor.rb → core/enumerable/test_every.rb} +2 -15
  130. data/test/core/enumerable/test_ewise.rb +23 -0
  131. data/test/core/enumerable/test_per.rb +18 -0
  132. data/test/core/enumerable/test_take.rb +13 -0
  133. data/test/core/kernel/test_deepcopy.rb +1 -1
  134. data/test/{more/test_1stclassmethod.rb → core/kernel/test_method.rb} +2 -7
  135. data/test/core/kernel/test_tap.rb +1 -1
  136. data/test/core/proc/test_curry.rb +11 -0
  137. data/test/core/string/test_bytes.rb +1 -1
  138. data/test/core/string/test_camelcase.rb +23 -6
  139. data/test/core/string/test_lines.rb +1 -1
  140. data/test/core/string/test_unfold.rb +14 -0
  141. data/test/{more → core}/test_blank.rb +0 -0
  142. data/test/{more → core}/test_boolean.rb +0 -0
  143. data/test/{more → core}/test_functor.rb +0 -0
  144. data/test/{lore → more}/test_basicobject.rb +0 -0
  145. data/test/more/{test_class_extension.rb → test_class_extend.rb} +6 -6
  146. data/test/{lore → more}/test_continuation.rb +0 -0
  147. data/test/{lore → more}/test_date.rb +0 -0
  148. data/test/more/{test_enumerablepass.rb → test_enumargs.rb} +2 -4
  149. data/test/more/{test_equatable.rb → test_equitable.rb} +2 -2
  150. data/test/more/{test_instantise.rb → test_instance_function.rb} +3 -2
  151. data/test/more/test_memoize.rb +1 -1
  152. data/test/{lore → more}/test_ostruct.rb +0 -0
  153. metadata +865 -1016
  154. data/RELEASE +0 -38
  155. data/doc/README.lore +0 -51
  156. data/doc/log/basic_stats/index.html +0 -39
  157. data/doc/log/changelog.html +0 -648
  158. data/doc/log/changelog.txt +0 -217
  159. data/doc/log/stats/index.html +0 -39
  160. data/doc/log/testlog.txt +0 -278
  161. data/doc/notes/CHANGES +0 -2529
  162. data/doc/rdoc/lore/classes/Array.html +0 -176
  163. data/doc/rdoc/lore/classes/CGI.html +0 -191
  164. data/doc/rdoc/lore/classes/Config.html +0 -135
  165. data/doc/rdoc/lore/classes/Continuation.html +0 -113
  166. data/doc/rdoc/lore/classes/Date.html +0 -631
  167. data/doc/rdoc/lore/classes/DateTime.html +0 -583
  168. data/doc/rdoc/lore/classes/Enumerable.html +0 -89
  169. data/doc/rdoc/lore/classes/Enumerable/Enumerator.html +0 -147
  170. data/doc/rdoc/lore/classes/File.html +0 -128
  171. data/doc/rdoc/lore/classes/FileUtils.html +0 -434
  172. data/doc/rdoc/lore/classes/GetoptLong.html +0 -118
  173. data/doc/rdoc/lore/classes/GetoptLong/DSL.html +0 -208
  174. data/doc/rdoc/lore/classes/Kernel.html +0 -135
  175. data/doc/rdoc/lore/classes/Logger.html +0 -229
  176. data/doc/rdoc/lore/classes/Logger/Ansicolor.html +0 -277
  177. data/doc/rdoc/lore/classes/Logger/LogDevice.html +0 -121
  178. data/doc/rdoc/lore/classes/NilClass.html +0 -119
  179. data/doc/rdoc/lore/classes/OpenStruct.html +0 -432
  180. data/doc/rdoc/lore/classes/Pathname.html +0 -353
  181. data/doc/rdoc/lore/classes/Set.html +0 -117
  182. data/doc/rdoc/lore/classes/Shellwords.html +0 -111
  183. data/doc/rdoc/lore/classes/String.html +0 -140
  184. data/doc/rdoc/lore/classes/Time.html +0 -154
  185. data/doc/rdoc/lore/classes/URI.html +0 -454
  186. data/doc/rdoc/lore/classes/URI/Hash.html +0 -105
  187. data/doc/rdoc/lore/classes/URI/Kernel.html +0 -122
  188. data/doc/rdoc/lore/classes/Zlib.html +0 -188
  189. data/doc/rdoc/lore/created.rid +0 -1
  190. data/doc/rdoc/lore/files/README.html +0 -286
  191. data/doc/rdoc/lore/files/doc/README_lore.html +0 -155
  192. data/doc/rdoc/lore/files/lib/lore/facets/basicobject_rb.html +0 -118
  193. data/doc/rdoc/lore/files/lib/lore/facets/cgi_rb.html +0 -111
  194. data/doc/rdoc/lore/files/lib/lore/facets/continuation_rb.html +0 -147
  195. data/doc/rdoc/lore/files/lib/lore/facets/date_rb.html +0 -97
  196. data/doc/rdoc/lore/files/lib/lore/facets/enumerator_rb.html +0 -111
  197. data/doc/rdoc/lore/files/lib/lore/facets/fileutils/head_rb.html +0 -96
  198. data/doc/rdoc/lore/files/lib/lore/facets/fileutils/safe_ln_rb.html +0 -96
  199. data/doc/rdoc/lore/files/lib/lore/facets/fileutils/slice_rb.html +0 -96
  200. data/doc/rdoc/lore/files/lib/lore/facets/fileutils/tail_rb.html +0 -96
  201. data/doc/rdoc/lore/files/lib/lore/facets/fileutils/wc_rb.html +0 -96
  202. data/doc/rdoc/lore/files/lib/lore/facets/fileutils/whereis_rb.html +0 -96
  203. data/doc/rdoc/lore/files/lib/lore/facets/fileutils/which_rb.html +0 -96
  204. data/doc/rdoc/lore/files/lib/lore/facets/fileutils_rb.html +0 -131
  205. data/doc/rdoc/lore/files/lib/lore/facets/getoptlong_rb.html +0 -135
  206. data/doc/rdoc/lore/files/lib/lore/facets/logger_rb.html +0 -142
  207. data/doc/rdoc/lore/files/lib/lore/facets/ostruct_rb.html +0 -135
  208. data/doc/rdoc/lore/files/lib/lore/facets/pathname_rb.html +0 -145
  209. data/doc/rdoc/lore/files/lib/lore/facets/rbconfig_rb.html +0 -124
  210. data/doc/rdoc/lore/files/lib/lore/facets/set_rb.html +0 -96
  211. data/doc/rdoc/lore/files/lib/lore/facets/shellwords_rb.html +0 -124
  212. data/doc/rdoc/lore/files/lib/lore/facets/uri_rb.html +0 -125
  213. data/doc/rdoc/lore/files/lib/lore/facets/yaml_rb.html +0 -146
  214. data/doc/rdoc/lore/files/lib/lore/facets/zlib_rb.html +0 -97
  215. data/doc/rdoc/lore/fr_class_index.html +0 -73
  216. data/doc/rdoc/lore/fr_file_index.html +0 -71
  217. data/doc/rdoc/lore/fr_method_index.html +0 -177
  218. data/doc/rdoc/lore/index.html +0 -26
  219. data/doc/rdoc/lore/rdoc-style.css +0 -177
  220. data/doc/release-notes/RELEASE-2.0.5 +0 -8
  221. data/doc/release-notes/RELEASE-2.1.0 +0 -9
  222. data/doc/release-notes/RELEASE-2.1.1 +0 -5
  223. data/doc/release-notes/RELEASE-2.1.2 +0 -6
  224. data/doc/release-notes/RELEASE-2.1.3 +0 -5
  225. data/doc/release-notes/RELEASE-2.2.0 +0 -14
  226. data/doc/release-notes/RELEASE-2.2.1 +0 -4
  227. data/doc/release-notes/RELEASE-2.3.0 +0 -6
  228. data/doc/release-notes/RELEASE-2.4.0 +0 -70
  229. data/doc/release-notes/RELEASE-2.4.1 +0 -8
  230. data/doc/release-notes/RELEASE-2.4.2 +0 -4
  231. data/doc/release-notes/RELEASE-2.4.3 +0 -78
  232. data/doc/release-notes/RELEASE-2.4.4 +0 -38
  233. data/doc/release-notes/RELEASE-2.4.5 +0 -37
  234. data/doc/release-notes/RELEASE-2.5.0 +0 -83
  235. data/lib/core/facets/kernel/instance.rb +0 -19
  236. data/lib/lore/facets/basicobject.rb +0 -14
  237. data/lib/lore/facets/enumerator.rb +0 -67
  238. data/lib/lore/facets/logger.rb +0 -291
  239. data/lib/more/facets/1stclassmethod.rb +0 -140
  240. data/lib/more/facets/advisable.rb +0 -162
  241. data/lib/more/facets/association.rb +0 -210
  242. data/lib/more/facets/attr.rb +0 -209
  243. data/lib/more/facets/basex.rb +0 -37
  244. data/lib/more/facets/bbcode.rb +0 -397
  245. data/lib/more/facets/bicrypt.rb +0 -265
  246. data/lib/more/facets/binreadable.rb +0 -221
  247. data/lib/more/facets/censor.rb +0 -97
  248. data/lib/more/facets/classmethods.rb +0 -199
  249. data/lib/more/facets/consoleutils.rb +0 -99
  250. data/lib/more/facets/crypt.rb +0 -166
  251. data/lib/more/facets/dependency.rb +0 -151
  252. data/lib/more/facets/downloader.rb +0 -281
  253. data/lib/more/facets/duplicable.rb +0 -43
  254. data/lib/more/facets/elementor.rb +0 -133
  255. data/lib/more/facets/filter.rb +0 -121
  256. data/lib/more/facets/heap.rb +0 -22
  257. data/lib/more/facets/infinity.rb +0 -193
  258. data/lib/more/facets/ini.rb +0 -264
  259. data/lib/more/facets/instantise.rb +0 -1
  260. data/lib/more/facets/instantize.rb +0 -95
  261. data/lib/more/facets/interval.rb +0 -282
  262. data/lib/more/facets/iteration.rb +0 -65
  263. data/lib/more/facets/linkedlist.rb +0 -222
  264. data/lib/more/facets/lrucache.rb +0 -157
  265. data/lib/more/facets/matcher.rb +0 -140
  266. data/lib/more/facets/memoizer.rb +0 -74
  267. data/lib/more/facets/minitar.rb +0 -1063
  268. data/lib/more/facets/nackclass.rb +0 -41
  269. data/lib/more/facets/net/smtp_tls.rb +0 -131
  270. data/lib/more/facets/nilstatus.rb +0 -48
  271. data/lib/more/facets/overload.rb +0 -94
  272. data/lib/more/facets/paramix.rb +0 -202
  273. data/lib/more/facets/pool.rb +0 -91
  274. data/lib/more/facets/pqueue.rb +0 -449
  275. data/lib/more/facets/pry.rb +0 -32
  276. data/lib/more/facets/reflection.rb +0 -145
  277. data/lib/more/facets/semaphore.rb +0 -92
  278. data/lib/more/facets/settings.rb +0 -248
  279. data/lib/more/facets/snapshot.rb +0 -209
  280. data/lib/more/facets/sparse_array.rb +0 -809
  281. data/lib/more/facets/string/mask.rb +0 -278
  282. data/lib/more/facets/string/obfuscate.rb +0 -65
  283. data/lib/more/facets/string/stylize.rb +0 -169
  284. data/lib/more/facets/string/words.rb +0 -167
  285. data/lib/more/facets/syncarray.rb +0 -114
  286. data/lib/more/facets/synchash.rb +0 -157
  287. data/lib/more/facets/typecast.rb +0 -261
  288. data/lib/more/facets/uninheritable.rb +0 -50
  289. data/lib/more/facets/xmlhash.rb +0 -112
  290. data/lib/more/facets/xoxo.rb +0 -259
  291. data/lib/more/facets/ziputils.rb +0 -490
  292. data/task/conflicts +0 -63
  293. data/task/coverage.rake +0 -37
  294. data/task/methods +0 -49
  295. data/task/rdoc.rake +0 -17
  296. data/task/setup.rake +0 -38
  297. data/task/test.rake +0 -145
  298. data/test/more/test_advisable.rb +0 -71
  299. data/test/more/test_association.rb +0 -38
  300. data/test/more/test_bbcode.rb +0 -21
  301. data/test/more/test_binreadable.rb +0 -50
  302. data/test/more/test_buildable.rb +0 -73
  303. data/test/more/test_classmethods.rb +0 -56
  304. data/test/more/test_crypt.rb +0 -32
  305. data/test/more/test_dependency.rb +0 -69
  306. data/test/more/test_elementwise.rb +0 -25
  307. data/test/more/test_infinity.rb +0 -40
  308. data/test/more/test_interval.rb +0 -151
  309. data/test/more/test_linkedlist.rb +0 -41
  310. data/test/more/test_lrucache.rb +0 -14
  311. data/test/more/test_overload.rb +0 -160
  312. data/test/more/test_paramix.rb +0 -170
  313. data/test/more/test_prototype.rb +0 -35
  314. data/test/more/test_snapshot.rb +0 -21
  315. data/test/more/test_sparsearray.rb +0 -279
  316. data/test/more/test_syncarray.rb +0 -15
  317. data/test/more/test_synchash.rb +0 -16
  318. data/test/more/test_typecast.rb +0 -54
  319. data/test/more/test_uninheritable.rb +0 -31
  320. data/test/more/test_xoxo.rb +0 -274
  321. data/test/test_facets.rb +0 -9
@@ -1,91 +0,0 @@
1
- # = Pool
2
- #
3
- # Generalized object pool implementation. Implemented as a thread
4
- # safe stack. Exclusive locking is needed both for push and pop.
5
- #
6
- # == Author
7
- #
8
- # * George Moschovitis
9
- #
10
- # == Todo
11
- #
12
- # * Could use the SizedQueue/Queue?
13
- #
14
- # == Copying
15
- #
16
- # Copyright (c) 2004 George Moschovitis
17
- #
18
- # Ruby License
19
- #
20
- # This module is free software. You may use, modify, and/or redistribute this
21
- # software under the same terms as Ruby.
22
- #
23
- # This program is distributed in the hope that it will be useful, but WITHOUT
24
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
25
- # FOR A PARTICULAR PURPOSE.
26
-
27
- require 'thread'
28
- require 'monitor'
29
-
30
- # = Pool
31
- #
32
- # Generalized object pool implementation. Implemented as a thread
33
- # safe stack. Exclusive locking is needed both for push and pop.
34
- #
35
- class Pool < Array
36
-
37
- include MonitorMixin
38
-
39
- def initialize
40
- super
41
- @cv = new_cond()
42
- end
43
-
44
- # Add, restore an object to the pool.
45
-
46
- def push(obj)
47
- synchronize do
48
- super
49
- @cv.signal()
50
- end
51
- end
52
-
53
- # Obtain an object from the pool.
54
-
55
- def pop
56
- synchronize do
57
- @cv.wait_while { empty? }
58
- super
59
- end
60
- end
61
-
62
- # Obtains an object, passes it to a block for processing
63
- # and restores it to the pool.
64
-
65
- def obtain
66
- result = nil
67
- begin
68
- obj = pop()
69
- result = yield(obj)
70
- ensure
71
- push(obj)
72
- end
73
- return result
74
- end
75
-
76
- end
77
-
78
-
79
-
80
- # _____ _
81
- # |_ _|__ ___| |_
82
- # | |/ _ \/ __| __|
83
- # | | __/\__ \ |_
84
- # |_|\___||___/\__|
85
- #
86
-
87
- # TODO
88
-
89
- =begin #testing
90
-
91
- =end
@@ -1,449 +0,0 @@
1
- # = PQueue
2
- #
3
- # Priority queue with array based heap.
4
- #
5
- # A priority queue is like a standard queue, except that each inserted
6
- # elements is given a certain priority, based on the result of the
7
- # comparison block given at instantiation time. Also, retrieving an element
8
- # from the queue will always return the one with the highest priority
9
- # (see #pop and #top).
10
- #
11
- # The default is to compare the elements in repect to their #> method.
12
- # For example, Numeric elements with higher values will have higher
13
- # priorities.
14
- #
15
- # == Thanks
16
- #
17
- # Rick Bradley 2003/02/02, patch for Ruby 1.6.5. Thank you!
18
- #
19
- # == Authors
20
- #
21
- # * Olivier Renaud
22
- # * K.Kodama (Created original PQueue.rb)
23
- # * Ronald Butler (reated original Heap.rb)
24
- #
25
- # == Copying
26
- #
27
- # Copyright (c) 2005 K.Kodama, Ronald Butler, Olivier Renaud
28
-
29
- # = PQueue
30
- #
31
- # Priority queue with array based heap.
32
- #
33
- # A priority queue is like a standard queue, except that each inserted
34
- # elements is given a certain priority, based on the result of the
35
- # comparison block given at instantiation time. Also, retrieving an element
36
- # from the queue will always return the one with the highest priority
37
- # (see #pop and #top).
38
- #
39
- # The default is to compare the elements in repect to their #> method.
40
- # For example, Numeric elements with higher values will have higher
41
- # priorities.
42
- #
43
- class PQueue
44
-
45
- # number of elements
46
- attr_reader :size
47
- # compare Proc
48
- attr_reader :gt
49
- attr_reader :qarray #:nodoc:
50
- protected :qarray
51
-
52
- # Returns a new priority queue.
53
- #
54
- # If elements are given, build the priority queue with these initial
55
- # values. The elements object must respond to #to_a.
56
- #
57
- # If a block is given, it will be used to determine the priority between
58
- # the elements.
59
- #
60
- # By default, the priority queue retrieves maximum elements first
61
- # (using the #> method).
62
- def initialize(elements=nil, &block) # :yields: a, b
63
- @qarray = [nil]
64
- @size = 0
65
- @gt = block || lambda {|a,b| a > b}
66
- replace(elements) if elements
67
- end
68
-
69
- private
70
-
71
- # Assumes that the tree is a heap, for nodes < k.
72
- #
73
- # The element at index k will go up until it finds its place.
74
- def upheap(k)
75
- k2 = k.div(2)
76
- v = @qarray[k]
77
- while k2 > 0 && @gt[v, @qarray[k2]]
78
- @qarray[k] = @qarray[k2]
79
- k = k2
80
- k2 = k2.div(2)
81
- end
82
- @qarray[k] = v
83
- end
84
-
85
- # Assumes the entire tree is a heap.
86
- #
87
- # The element at index k will go down until it finds its place.
88
- def downheap(k)
89
- v = @qarray[k]
90
- q2 = @size.div(2)
91
- loop {
92
- break if k > q2
93
- j = 2 * k
94
- if j < @size && @gt[@qarray[j+1], @qarray[j]]
95
- j += 1
96
- end
97
- break if @gt[v, @qarray[j]]
98
- @qarray[k] = @qarray[j]
99
- k = j
100
- }
101
- @qarray[k] = v;
102
- end
103
-
104
-
105
- # Recursive version of heapify. I kept the code, since it may be
106
- # easier to understand than the non-recursive one.
107
- # def heapify
108
- # @size.div(2).downto(1) {|i| h(i)}
109
- # end
110
- # def h(t)
111
- # l = 2 * t
112
- # r = l + 1
113
- # hi = if r > @size || @gt[@qarray[l],@qarray[r]] then l else r end
114
- # if @gt[@qarray[hi],@qarray[t]]
115
- # @qarray[hi], @qarray[t] = @qarray[t], @qarray[hi]
116
- # h(hi) if hi <= @size.div(2)
117
- # end
118
- # end
119
-
120
- # Make a heap out of an unordered array.
121
- def heapify
122
- @size.div(2).downto(1) do |t|
123
- begin
124
- l = 2 * t
125
- r = l + 1
126
- hi = if r > @size || @gt[@qarray[l],@qarray[r]] then l else r end
127
- if @gt[@qarray[hi],@qarray[t]]
128
- @qarray[hi], @qarray[t] = @qarray[t], @qarray[hi]
129
- if hi <= @size.div(2)
130
- t = hi
131
- redo
132
- end # if
133
- end #if
134
- end #begin
135
- end # downto
136
- end
137
-
138
- public
139
-
140
- # Add an element in the priority queue.
141
- #
142
- # The insertion time is O(log n), with n the size of the queue.
143
- def push(v)
144
- @size += 1
145
- @qarray[@size] = v
146
- upheap(@size)
147
- return self
148
- end
149
-
150
- alias :<< :push
151
-
152
- # Return the element with the highest priority and remove it from
153
- # the queue.
154
- #
155
- # The highest priority is determined by the block given at instanciation
156
- # time.
157
- #
158
- # The deletion time is O(log n), with n the size of the queue.
159
- #
160
- # Return nil if the queue is empty.
161
- def pop
162
- return nil if empty?
163
- res = @qarray[1]
164
- @qarray[1] = @qarray[@size]
165
- @size -= 1
166
- downheap(1)
167
- return res
168
- end
169
-
170
- # Return the element with the highest priority.
171
- def top
172
- return nil if empty?
173
- return @qarray[1]
174
- end
175
-
176
- # Add more than one element at the same time. See #push.
177
- #
178
- # The elements object must respond to #to_a, or to be a PQueue itself.
179
- def push_all(elements)
180
- if empty?
181
- if elements.kind_of?(PQueue)
182
- initialize_copy(elements)
183
- else
184
- replace(elements)
185
- end
186
- else
187
- if elements.kind_of?(PQueue)
188
- @qarray[@size + 1, elements.size] = elements.qarray[1..-1]
189
- elements.size.times{ @size += 1; upheap(@size)}
190
- else
191
- ary = elements.to_a
192
- @qarray[@size + 1, ary.size] = ary
193
- ary.size.times{ @size += 1; upheap(@size)}
194
- end
195
- end
196
- return self
197
- end
198
-
199
- alias :merge :push_all
200
-
201
-
202
- # Return top n-element as a sorted array.
203
- def pop_array(n=@size)
204
- ary = []
205
- n.times{ary.push(pop)}
206
- return ary
207
- end
208
-
209
-
210
- # True if there is no more elements left in the priority queue.
211
- def empty?
212
- return @size.zero?
213
- end
214
-
215
- # Remove all elements from the priority queue.
216
- def clear
217
- @qarray.replace([nil])
218
- @size = 0
219
- return self
220
- end
221
-
222
- # Replace the content of the heap by the new elements.
223
- #
224
- # The elements object must respond to #to_a, or to be a PQueue itself.
225
- def replace(elements)
226
- if elements.kind_of?(PQueue)
227
- initialize_copy(elements)
228
- else
229
- @qarray.replace([nil] + elements.to_a)
230
- @size = @qarray.size - 1
231
- heapify
232
- end
233
- return self
234
- end
235
-
236
- # Return a sorted array, with highest priority first.
237
- def to_a
238
- old_qarray = @qarray.dup
239
- old_size = @size
240
- res = pop_array
241
- @qarray = old_qarray
242
- @size = old_size
243
- return res
244
- end
245
-
246
- alias :sort :to_a
247
-
248
- # Replace the top element with the given one, and return this top element.
249
- #
250
- # Equivalent to successively calling #pop and #push(v).
251
- def replace_top(v)
252
- # replace top element
253
- if empty?
254
- @qarray[1] = v
255
- @size += 1
256
- return nil
257
- else
258
- res = @qarray[1]
259
- @qarray[1] = v
260
- downheap(1)
261
- return res
262
- end
263
- end
264
-
265
- # Return true if the given object is present in the queue.
266
- def include?(element)
267
- return @qarray.include?(element)
268
- end
269
-
270
- # Iterate over the ordered elements, destructively.
271
- def each_pop #:yields: popped
272
- until empty?
273
- yield pop
274
- end
275
- return nil
276
- end
277
-
278
- # Pretty print
279
- def inspect
280
- "<#{self.class}: size=#{@size}, top=#{top || "nil"}>"
281
- end
282
-
283
- ###########################
284
- ### Override Object methods
285
-
286
- # Return true if the queues contain equal elements.
287
- def ==(other)
288
- return size == other.size && to_a == other.to_a
289
- end
290
-
291
- private
292
-
293
- def initialize_copy(other)
294
- @gt = other.gt
295
- @qarray = other.qarray.dup
296
- @size = other.size
297
- end
298
- end # class PQueue
299
-
300
-
301
-
302
- # _____ _
303
- # |_ _|__ ___| |_
304
- # | |/ _ \/ __| __|
305
- # | | __/\__ \ |_
306
- # |_|\___||___/\__|
307
- #
308
-
309
- =begin #test
310
-
311
- require 'test/unit'
312
-
313
- class TC_PQueue < Test::Unit::TestCase
314
- ARY_TEST = [2,6,1,3,8,15,0,-4,7,8,10]
315
- ARY_TEST_2 = [25,10,5,13,16,9,16,12]
316
-
317
- def test_initialize
318
- assert_nothing_raised { PQueue.new }
319
- assert_nothing_raised { PQueue.new([3]) }
320
- assert_nothing_raised { PQueue.new(ARY_TEST) }
321
- assert_nothing_raised { PQueue.new {|a,b| a<b} }
322
- assert_nothing_raised { PQueue.new([3]) {|a,b| a<b} }
323
- assert_nothing_raised { PQueue.new(ARY_TEST) {|a,b| a<b} }
324
- end
325
-
326
- def test_top
327
- assert_equal(ARY_TEST.max, PQueue.new(ARY_TEST).top)
328
- assert_nil(PQueue.new.top)
329
- end
330
-
331
- def test_pop
332
- sorted_ary = ARY_TEST.sort
333
- q = PQueue.new(ARY_TEST)
334
- ARY_TEST.size.times do
335
- assert_equal(sorted_ary.pop, q.pop)
336
- end
337
- assert_equal(0, q.size)
338
- assert_nil(PQueue.new.pop)
339
- end
340
-
341
- def test_insertion
342
- q = PQueue.new(ARY_TEST)
343
- assert_equal(ARY_TEST.size, q.size)
344
-
345
- ret = q.push(24)
346
- assert_equal(q, ret)
347
- assert_equal(ARY_TEST.size+1, q.size)
348
-
349
- ret = q.push_all(ARY_TEST_2)
350
- assert_equal(q, ret)
351
- assert_equal(ARY_TEST.size+1+ARY_TEST_2.size, q.size)
352
-
353
- q = PQueue.new(ARY_TEST)
354
- r = PQueue.new(ARY_TEST_2)
355
- q.push_all(r)
356
- assert_equal(ARY_TEST.size + ARY_TEST_2.size, q.size)
357
- end
358
-
359
- def test_clear
360
- q = PQueue.new(ARY_TEST).clear
361
- assert_equal(q, q.clear)
362
- assert_equal(0, q.size)
363
- end
364
-
365
- def test_replace
366
- q = PQueue.new(ARY_TEST)
367
- q.replace(ARY_TEST_2)
368
- assert_equal(ARY_TEST_2.size, q.size)
369
-
370
- q = PQueue.new(ARY_TEST)
371
- q.replace(PQueue.new(ARY_TEST_2))
372
- assert_equal(ARY_TEST_2.size, q.size)
373
- end
374
-
375
- def test_inspect
376
- assert_equal("<PQueue: size=#{ARY_TEST.size}, top=#{ARY_TEST.max}>",
377
- PQueue.new(ARY_TEST).inspect)
378
- end
379
-
380
- def test_to_a
381
- q = PQueue.new(ARY_TEST)
382
- assert_equal(ARY_TEST.sort.reverse, q.sort)
383
- q = PQueue.new(0..4)
384
- assert_equal([4,3,2,1,0], q.sort)
385
- end
386
-
387
- def pop_array
388
- q = PQueue.new(ARY_TEST)
389
- assert_equal(ARY_TEST.sort.reverse[0..5], q.pop_array(5))
390
- q = PQueue.new(ARY_TEST)
391
- assert_equal(ARY_TEST.sort.reverse, q.pop_array)
392
- end
393
-
394
- def test_include
395
- q = PQueue.new(ARY_TEST + [21] + ARY_TEST_2)
396
- assert_equal(true, q.include?(21))
397
-
398
- q = PQueue.new(ARY_TEST - [15])
399
- assert_equal(false, q.include?(15))
400
- end
401
-
402
- def test_assert_equal
403
- assert_equal(PQueue.new, PQueue.new)
404
- assert_equal(PQueue.new(ARY_TEST), PQueue.new(ARY_TEST.sort_by{rand}))
405
- end
406
-
407
- def test_replace_top
408
- q = PQueue.new
409
- assert_nil(q.replace_top(6))
410
- assert_equal(6, q.top)
411
-
412
- q = PQueue.new(ARY_TEST)
413
- h = PQueue.new(ARY_TEST)
414
- q.pop; q.push(11)
415
- h.replace_top(11)
416
- assert_equal(q, h)
417
- end
418
-
419
- def test_dup
420
- q = PQueue.new(ARY_TEST)
421
- assert_equal(q, q.dup)
422
- end
423
-
424
- def test_array_copied
425
- ary = ARY_TEST.dup
426
- q = PQueue.new(ary)
427
- q.pop
428
- assert_equal(ARY_TEST, ary)
429
-
430
- ary = ARY_TEST.dup
431
- q = PQueue.new
432
- q.replace(ary)
433
- q.pop
434
- assert_equal(ARY_TEST, ary)
435
-
436
- ary = ARY_TEST.dup
437
- q = PQueue.new([1])
438
- q.push_all(ary)
439
- q.pop
440
- assert_equal(ARY_TEST, ary)
441
-
442
- q = PQueue.new(ARY_TEST)
443
- r = q.dup
444
- q.pop
445
- assert_not_equal(q, r)
446
- end
447
- end
448
-
449
- =end