facets 2.6.0 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
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