carats 0.3.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 (422) hide show
  1. data/ChangeLog +2 -0
  2. data/LICENSE +5 -0
  3. data/README +67 -0
  4. data/Reapfile +72 -0
  5. data/ToDo +24 -0
  6. data/bench/b_harray.rb +49 -0
  7. data/bench/b_range.rb +64 -0
  8. data/demo/ansicolor/cdiff.rb +20 -0
  9. data/demo/ansicolor/example.rb +82 -0
  10. data/demo/io-reactor/chatserver.rb +347 -0
  11. data/doc/classes/Array.html +172 -0
  12. data/doc/classes/BBCode.html +638 -0
  13. data/doc/classes/BinaryReader.html +675 -0
  14. data/doc/classes/Binding.html +223 -0
  15. data/doc/classes/ByteOrder.html +284 -0
  16. data/doc/classes/Class.html +189 -0
  17. data/doc/classes/Constant.html +785 -0
  18. data/doc/classes/Constant/CGS.html +609 -0
  19. data/doc/classes/Continuation.html +113 -0
  20. data/doc/classes/Coroutine.html +387 -0
  21. data/doc/classes/CountingSemaphore.html +337 -0
  22. data/doc/classes/CrossCase.html +561 -0
  23. data/doc/classes/DynamicMixin.html +185 -0
  24. data/doc/classes/EnumerableWithArgs.html +550 -0
  25. data/doc/classes/Expect.html +428 -0
  26. data/doc/classes/Expect/DefaultChain.html +113 -0
  27. data/doc/classes/Expect/SeparatedPattern.html +223 -0
  28. data/doc/classes/Expect/Timeout.html +167 -0
  29. data/doc/classes/Expect/UnmatchedMessage.html +160 -0
  30. data/doc/classes/FileList.html +833 -0
  31. data/doc/classes/FloatString.html +534 -0
  32. data/doc/classes/Functor.html +211 -0
  33. data/doc/classes/HArray.html +1872 -0
  34. data/doc/classes/HTML.html +328 -0
  35. data/doc/classes/Heap.html +683 -0
  36. data/doc/classes/Heap/EmptyHeapException.html +111 -0
  37. data/doc/classes/Heap/Max.html +176 -0
  38. data/doc/classes/Heap/Min.html +176 -0
  39. data/doc/classes/IO.html +108 -0
  40. data/doc/classes/IO/Reactor.html +790 -0
  41. data/doc/classes/IO/Redirect.html +289 -0
  42. data/doc/classes/Infinity.html +320 -0
  43. data/doc/classes/Interval.html +1014 -0
  44. data/doc/classes/InvalidNackError.html +161 -0
  45. data/doc/classes/Kernel.html +204 -0
  46. data/doc/classes/Lisp.html +1132 -0
  47. data/doc/classes/Lisp/DottedPair.html +379 -0
  48. data/doc/classes/Lisp/Format.html +178 -0
  49. data/doc/classes/Lisp/Format/ArgumentError.html +126 -0
  50. data/doc/classes/Lisp/Format/Directives.html +155 -0
  51. data/doc/classes/Lisp/Format/Directives/ArgJump.html +178 -0
  52. data/doc/classes/Lisp/Format/Directives/Ascii.html +119 -0
  53. data/doc/classes/Lisp/Format/Directives/BeginCaseConversion.html +185 -0
  54. data/doc/classes/Lisp/Format/Directives/BeginConditional.html +307 -0
  55. data/doc/classes/Lisp/Format/Directives/BeginIteration.html +338 -0
  56. data/doc/classes/Lisp/Format/Directives/Binary.html +157 -0
  57. data/doc/classes/Lisp/Format/Directives/Character.html +228 -0
  58. data/doc/classes/Lisp/Format/Directives/CharacterDirective.html +203 -0
  59. data/doc/classes/Lisp/Format/Directives/ClauseSeparator.html +166 -0
  60. data/doc/classes/Lisp/Format/Directives/Decimal.html +119 -0
  61. data/doc/classes/Lisp/Format/Directives/Directive.html +397 -0
  62. data/doc/classes/Lisp/Format/Directives/DollarFP.html +205 -0
  63. data/doc/classes/Lisp/Format/Directives/EndCaseConversion.html +174 -0
  64. data/doc/classes/Lisp/Format/Directives/EndConditional.html +159 -0
  65. data/doc/classes/Lisp/Format/Directives/EndIteration.html +163 -0
  66. data/doc/classes/Lisp/Format/Directives/ExpFP.html +252 -0
  67. data/doc/classes/Lisp/Format/Directives/FFFP.html +224 -0
  68. data/doc/classes/Lisp/Format/Directives/Factory.html +180 -0
  69. data/doc/classes/Lisp/Format/Directives/FreshLine.html +175 -0
  70. data/doc/classes/Lisp/Format/Directives/GeneralFP.html +265 -0
  71. data/doc/classes/Lisp/Format/Directives/Hexadecimal.html +157 -0
  72. data/doc/classes/Lisp/Format/Directives/Indirection.html +183 -0
  73. data/doc/classes/Lisp/Format/Directives/Literal.html +187 -0
  74. data/doc/classes/Lisp/Format/Directives/NewLine.html +158 -0
  75. data/doc/classes/Lisp/Format/Directives/NewPage.html +158 -0
  76. data/doc/classes/Lisp/Format/Directives/Number.html +243 -0
  77. data/doc/classes/Lisp/Format/Directives/Octal.html +157 -0
  78. data/doc/classes/Lisp/Format/Directives/Plural.html +177 -0
  79. data/doc/classes/Lisp/Format/Directives/Print.html +237 -0
  80. data/doc/classes/Lisp/Format/Directives/Radix.html +432 -0
  81. data/doc/classes/Lisp/Format/Directives/SExpression.html +157 -0
  82. data/doc/classes/Lisp/Format/Directives/SkipWhitespace.html +165 -0
  83. data/doc/classes/Lisp/Format/Directives/Tabulate.html +198 -0
  84. data/doc/classes/Lisp/Format/Directives/Tilde.html +158 -0
  85. data/doc/classes/Lisp/Format/Directives/UnknownDirectiveError.html +117 -0
  86. data/doc/classes/Lisp/Format/Formatter.html +193 -0
  87. data/doc/classes/Lisp/Format/IncompleteParameterError.html +119 -0
  88. data/doc/classes/Lisp/Format/IndexError.html +126 -0
  89. data/doc/classes/Lisp/Format/Lexer.html +479 -0
  90. data/doc/classes/Lisp/Format/MalformedError.html +119 -0
  91. data/doc/classes/Lisp/Format/MissingParameterError.html +119 -0
  92. data/doc/classes/Lisp/Format/ModifierError.html +119 -0
  93. data/doc/classes/Lisp/Format/Output.html +239 -0
  94. data/doc/classes/Lisp/Format/ParameterError.html +126 -0
  95. data/doc/classes/Lisp/Format/Parameters.html +123 -0
  96. data/doc/classes/Lisp/Format/Parameters/Argument.html +172 -0
  97. data/doc/classes/Lisp/Format/Parameters/ArgumentCount.html +159 -0
  98. data/doc/classes/Lisp/Format/Parameters/Character.html +119 -0
  99. data/doc/classes/Lisp/Format/Parameters/Default.html +120 -0
  100. data/doc/classes/Lisp/Format/Parameters/Integer.html +119 -0
  101. data/doc/classes/Lisp/Format/Parameters/Parameter.html +206 -0
  102. data/doc/classes/Lisp/Format/Parser.html +212 -0
  103. data/doc/classes/Lisp/Format/Positioned.html +166 -0
  104. data/doc/classes/Lisp/Format/State.html +455 -0
  105. data/doc/classes/Lisp/Format/SyntaxError.html +126 -0
  106. data/doc/classes/Method.html +274 -0
  107. data/doc/classes/Method/DuckHunter.html +281 -0
  108. data/doc/classes/Module.html +709 -0
  109. data/doc/classes/Multiton.html +284 -0
  110. data/doc/classes/Multiton/New.html +164 -0
  111. data/doc/classes/Multiton/Semi.html +155 -0
  112. data/doc/classes/NackClass.html +322 -0
  113. data/doc/classes/NilClass.html +231 -0
  114. data/doc/classes/NilComparable.html +179 -0
  115. data/doc/classes/NotCopyable.html +273 -0
  116. data/doc/classes/Object.html +261 -0
  117. data/doc/classes/OpenStructable.html +346 -0
  118. data/doc/classes/OrderedHash.html +939 -0
  119. data/doc/classes/Parser.html +515 -0
  120. data/doc/classes/Parser/Main.html +178 -0
  121. data/doc/classes/Parser/Marker.html +475 -0
  122. data/doc/classes/Parser/Registry.html +354 -0
  123. data/doc/classes/Parser/Token.html +399 -0
  124. data/doc/classes/Parser/UnitToken.html +222 -0
  125. data/doc/classes/Ref.html +230 -0
  126. data/doc/classes/SimpleStringIO.html +183 -0
  127. data/doc/classes/StaticHash.html +202 -0
  128. data/doc/classes/String.html +172 -0
  129. data/doc/classes/Struct.html +181 -0
  130. data/doc/classes/SuperStruct.html +382 -0
  131. data/doc/classes/Term.html +156 -0
  132. data/doc/classes/Term/ANSIColor.html +185 -0
  133. data/doc/classes/Text.html +138 -0
  134. data/doc/classes/Text/Soundex.html +222 -0
  135. data/doc/classes/TextTagIterator.html +911 -0
  136. data/doc/classes/Time.html +119 -0
  137. data/doc/classes/Time/Limit.html +303 -0
  138. data/doc/classes/Time/Limit/Dummy.html +181 -0
  139. data/doc/classes/Timer.html +351 -0
  140. data/doc/classes/TracePoint.html +532 -0
  141. data/doc/classes/Tuple.html +178 -0
  142. data/doc/classes/Uninheritable.html +213 -0
  143. data/doc/classes/Version.html +783 -0
  144. data/doc/created.rid +1 -0
  145. data/doc/files/LICENSE.html +113 -0
  146. data/doc/files/README.html +201 -0
  147. data/doc/files/lib/carat/1st_rb.html +107 -0
  148. data/doc/files/lib/carat/ansicolor_rb.html +146 -0
  149. data/doc/files/lib/carat/attr_rb.html +101 -0
  150. data/doc/files/lib/carat/bbcode_rb.html +152 -0
  151. data/doc/files/lib/carat/binaryreader_rb.html +114 -0
  152. data/doc/files/lib/carat/binding-of-caller_rb.html +108 -0
  153. data/doc/files/lib/carat/byteorder_rb.html +107 -0
  154. data/doc/files/lib/carat/constant_rb.html +167 -0
  155. data/doc/files/lib/carat/coroutine_rb.html +156 -0
  156. data/doc/files/lib/carat/crosscase_rb.html +224 -0
  157. data/doc/files/lib/carat/duckhunter_rb.html +165 -0
  158. data/doc/files/lib/carat/dynamic-mixin_rb.html +101 -0
  159. data/doc/files/lib/carat/enumerable-args_rb.html +140 -0
  160. data/doc/files/lib/carat/expect_rb.html +137 -0
  161. data/doc/files/lib/carat/filelist_rb.html +130 -0
  162. data/doc/files/lib/carat/floatstring_rb.html +126 -0
  163. data/doc/files/lib/carat/functor_rb.html +140 -0
  164. data/doc/files/lib/carat/harray_rb.html +128 -0
  165. data/doc/files/lib/carat/heap_rb.html +154 -0
  166. data/doc/files/lib/carat/html-helpers_rb.html +116 -0
  167. data/doc/files/lib/carat/infinity_rb.html +142 -0
  168. data/doc/files/lib/carat/init_rb.html +127 -0
  169. data/doc/files/lib/carat/interval_rb.html +162 -0
  170. data/doc/files/lib/carat/io-reactor_rb.html +211 -0
  171. data/doc/files/lib/carat/io-redirect_rb.html +132 -0
  172. data/doc/files/lib/carat/lisp-format_rb.html +187 -0
  173. data/doc/files/lib/carat/lisp_rb.html +152 -0
  174. data/doc/files/lib/carat/macro_rb.html +129 -0
  175. data/doc/files/lib/carat/multiton_rb.html +178 -0
  176. data/doc/files/lib/carat/nack_rb.html +193 -0
  177. data/doc/files/lib/carat/nil-comparable_rb.html +126 -0
  178. data/doc/files/lib/carat/nil-missing_rb.html +101 -0
  179. data/doc/files/lib/carat/notcopyable_rb.html +166 -0
  180. data/doc/files/lib/carat/orderedhash_rb.html +107 -0
  181. data/doc/files/lib/carat/ostructable_rb.html +157 -0
  182. data/doc/files/lib/carat/parser-old_rb.html +239 -0
  183. data/doc/files/lib/carat/parser_rb.html +244 -0
  184. data/doc/files/lib/carat/ref_rb.html +107 -0
  185. data/doc/files/lib/carat/semaphore_rb.html +132 -0
  186. data/doc/files/lib/carat/snapshot_rb.html +152 -0
  187. data/doc/files/lib/carat/soundex_rb.html +128 -0
  188. data/doc/files/lib/carat/sstruct_rb.html +142 -0
  189. data/doc/files/lib/carat/statichash_rb.html +150 -0
  190. data/doc/files/lib/carat/tagiter_rb.html +236 -0
  191. data/doc/files/lib/carat/timelimit_rb.html +136 -0
  192. data/doc/files/lib/carat/timer_rb.html +153 -0
  193. data/doc/files/lib/carat/tracepoint_rb.html +160 -0
  194. data/doc/files/lib/carat/tuple_rb.html +123 -0
  195. data/doc/files/lib/carat/uninheritable_rb.html +101 -0
  196. data/doc/files/lib/carat/version_rb.html +141 -0
  197. data/doc/fr_class_index.html +159 -0
  198. data/doc/fr_file_index.html +78 -0
  199. data/doc/fr_method_index.html +663 -0
  200. data/doc/index.html +24 -0
  201. data/doc/rdoc-style.css +208 -0
  202. data/lib/carat-dev/README +11 -0
  203. data/lib/carat-dev/access-blocks/access_blocks.rb +42 -0
  204. data/lib/carat-dev/association/association.rb +70 -0
  205. data/lib/carat-dev/blankslate/blankslate.rb +51 -0
  206. data/lib/carat-dev/breakpoint.rb +518 -0
  207. data/lib/carat-dev/class-constructor/constructor_methods.rb +78 -0
  208. data/lib/carat-dev/class-constructor/tc_constructor.rb +35 -0
  209. data/lib/carat-dev/closecall/closecall-test.rb +39 -0
  210. data/lib/carat-dev/closecall/closecall.rb +101 -0
  211. data/lib/carat-dev/commandrunner/commandrunner.rb +100 -0
  212. data/lib/carat-dev/conditional/conditionals.rb +106 -0
  213. data/lib/carat-dev/daemon/daemon.rb +70 -0
  214. data/lib/carat-dev/detach/detach.rb +363 -0
  215. data/lib/carat-dev/detach/tc_detach.rb +57 -0
  216. data/lib/carat-dev/import-module/import-module-0.81.tar.gz +0 -0
  217. data/lib/carat-dev/import-module/import-module-0.81/LICENSE +1 -0
  218. data/lib/carat-dev/import-module/import-module-0.81/Makefile +11 -0
  219. data/lib/carat-dev/import-module/import-module-0.81/README +4 -0
  220. data/lib/carat-dev/import-module/import-module-0.81/dev-lib/import-module-hash.rb +49 -0
  221. data/lib/carat-dev/import-module/import-module-0.81/dev-lib/import-module-pip.rb +71 -0
  222. data/lib/carat-dev/import-module/import-module-0.81/dev-lib/import-module-unbound-method.rb +36 -0
  223. data/lib/carat-dev/import-module/import-module-0.81/doc/README-ja.html +293 -0
  224. data/lib/carat-dev/import-module/import-module-0.81/doc/README-ja.rd +306 -0
  225. data/lib/carat-dev/import-module/import-module-0.81/doc/README.html +290 -0
  226. data/lib/carat-dev/import-module/import-module-0.81/doc/README.rd +303 -0
  227. data/lib/carat-dev/import-module/import-module-0.81/doc/style.css +85 -0
  228. data/lib/carat-dev/import-module/import-module-0.81/install.rb +99 -0
  229. data/lib/carat-dev/import-module/import-module-0.81/lib/import-module-single-thread.rb +84 -0
  230. data/lib/carat-dev/import-module/import-module-0.81/lib/import-module.rb +493 -0
  231. data/lib/carat-dev/import-module/import-module-0.81/test/Makefile +2 -0
  232. data/lib/carat-dev/import-module/import-module-0.81/test/test +91 -0
  233. data/lib/carat-dev/import-module/import-module-0.81/test/test-import-module.rb +936 -0
  234. data/lib/carat-dev/import-module/import-module-0.81/test/test-import_scope.rb +33 -0
  235. data/lib/carat-dev/import-module/import-module-0.81/test/test-scope_import.rb +33 -0
  236. data/lib/carat-dev/import-module/import-module-0.81/test/test-time.rb +184 -0
  237. data/lib/carat-dev/import-module/import-module-0.81/test/test.sh +91 -0
  238. data/lib/carat-dev/import-module/import-module-0.81/test/time.rb +135 -0
  239. data/lib/carat-dev/import-module/import-module-0.81/test/times-do.sh +10 -0
  240. data/lib/carat-dev/interface_work/SCRAP/i-contracts.rb +37 -0
  241. data/lib/carat-dev/interface_work/SCRAP/interface.rb +105 -0
  242. data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0.zip +0 -0
  243. data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/CHANGES +3 -0
  244. data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/MANIFEST +15 -0
  245. data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/README +32 -0
  246. data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/doc/interface.rd +73 -0
  247. data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/doc/interface.txt +94 -0
  248. data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/install.rb +16 -0
  249. data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/lib/interface.rb +50 -0
  250. data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/test/tc_interface.rb +51 -0
  251. data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/test/test.rb +29 -0
  252. data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/test/test_instance.rb +24 -0
  253. data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/test/test_sub.rb +29 -0
  254. data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/test/test_unrequire.rb +28 -0
  255. data/lib/carat-dev/interface_work/contracts/contract.zip +0 -0
  256. data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.html +376 -0
  257. data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.src/M000001.html +23 -0
  258. data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.src/M000002.html +18 -0
  259. data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.src/M000003.html +19 -0
  260. data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.src/M000004.html +29 -0
  261. data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.src/M000005.html +18 -0
  262. data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.src/M000006.html +18 -0
  263. data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract/ContractError.html +142 -0
  264. data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract/ContractException.html +153 -0
  265. data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract/ContractMismatch.html +125 -0
  266. data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Module.html +157 -0
  267. data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Module.src/M000007.html +112 -0
  268. data/lib/carat-dev/interface_work/contracts/contract/doc/created.rid +1 -0
  269. data/lib/carat-dev/interface_work/contracts/contract/doc/files/lib/contract/assertions_rb.html +109 -0
  270. data/lib/carat-dev/interface_work/contracts/contract/doc/files/lib/contract/exception_rb.html +108 -0
  271. data/lib/carat-dev/interface_work/contracts/contract/doc/files/lib/contract/integration_rb.html +108 -0
  272. data/lib/carat-dev/interface_work/contracts/contract/doc/files/lib/contract/overrides_rb.html +109 -0
  273. data/lib/carat-dev/interface_work/contracts/contract/doc/files/lib/contract_rb.html +114 -0
  274. data/lib/carat-dev/interface_work/contracts/contract/doc/fr_class_index.html +31 -0
  275. data/lib/carat-dev/interface_work/contracts/contract/doc/fr_file_index.html +31 -0
  276. data/lib/carat-dev/interface_work/contracts/contract/doc/fr_method_index.html +33 -0
  277. data/lib/carat-dev/interface_work/contracts/contract/doc/index.html +24 -0
  278. data/lib/carat-dev/interface_work/contracts/contract/doc/rdoc-style.css +208 -0
  279. data/lib/carat-dev/interface_work/contracts/contract/lib/contract.rb +88 -0
  280. data/lib/carat-dev/interface_work/contracts/contract/lib/contract/assertions.rb +37 -0
  281. data/lib/carat-dev/interface_work/contracts/contract/lib/contract/exception.rb +92 -0
  282. data/lib/carat-dev/interface_work/contracts/contract/lib/contract/integration.rb +132 -0
  283. data/lib/carat-dev/interface_work/contracts/contract/lib/contract/overrides.rb +32 -0
  284. data/lib/carat-dev/interface_work/must.rb +37 -0
  285. data/lib/carat-dev/interface_work/type.rb +232 -0
  286. data/lib/carat-dev/main/tc_toplevel.rb +23 -0
  287. data/lib/carat-dev/main/toplevel.rb +33 -0
  288. data/lib/carat-dev/main/toplevel_test.rb +24 -0
  289. data/lib/carat-dev/misc/1.rb +40 -0
  290. data/lib/carat-dev/misc/misc.rb +44 -0
  291. data/lib/carat-dev/misc/sys.rb +186 -0
  292. data/lib/carat-dev/misc/temp.rb +1 -0
  293. data/lib/carat-dev/misc/utils.rb +518 -0
  294. data/lib/carat-dev/predicate/predicate.rb +109 -0
  295. data/lib/carat-dev/predicate/predicate_test.rb +67 -0
  296. data/lib/carat-dev/premshree.rb +40 -0
  297. data/lib/carat-dev/priority-queue/pqueue.rb +183 -0
  298. data/lib/carat-dev/priority-queue/priorityqueue.rb +84 -0
  299. data/lib/carat-dev/quaternion/quaternion.rb +529 -0
  300. data/lib/carat-dev/range.rb +259 -0
  301. data/lib/carat-dev/system/rubyinfo.rb +75 -0
  302. data/lib/carat-dev/system/system.rb +105 -0
  303. data/lib/carat-dev/tc_range.rb +118 -0
  304. data/lib/carat-dev/timer/timer-doc/classes/Timer.html +291 -0
  305. data/lib/carat-dev/timer/timer-doc/classes/Timer.src/M000001.html +26 -0
  306. data/lib/carat-dev/timer/timer-doc/classes/Timer.src/M000002.html +19 -0
  307. data/lib/carat-dev/timer/timer-doc/classes/Timer.src/M000003.html +18 -0
  308. data/lib/carat-dev/timer/timer-doc/classes/Timer.src/M000004.html +18 -0
  309. data/lib/carat-dev/timer/timer-doc/classes/Timer.src/M000005.html +21 -0
  310. data/lib/carat-dev/timer/timer-doc/classes/Timer.src/M000006.html +23 -0
  311. data/lib/carat-dev/timer/timer-doc/created.rid +1 -0
  312. data/lib/carat-dev/timer/timer-doc/files/timer_rb.html +144 -0
  313. data/lib/carat-dev/timer/timer-doc/fr_class_index.html +27 -0
  314. data/lib/carat-dev/timer/timer-doc/fr_file_index.html +27 -0
  315. data/lib/carat-dev/timer/timer-doc/fr_method_index.html +32 -0
  316. data/lib/carat-dev/timer/timer-doc/index.html +24 -0
  317. data/lib/carat-dev/timer/timer-doc/rdoc-style.css +208 -0
  318. data/lib/carat-dev/timer/timer.rb +160 -0
  319. data/lib/carat-dev/vars/vars.rb +62 -0
  320. data/lib/carat/1st.rb +58 -0
  321. data/lib/carat/ansicolor.rb +122 -0
  322. data/lib/carat/attr.rb +342 -0
  323. data/lib/carat/bbcode.rb +352 -0
  324. data/lib/carat/binaryreader.rb +170 -0
  325. data/lib/carat/binding-of-caller.rb +83 -0
  326. data/lib/carat/byteorder.rb +34 -0
  327. data/lib/carat/constant.rb +287 -0
  328. data/lib/carat/coroutine.rb +102 -0
  329. data/lib/carat/crosscase.rb +309 -0
  330. data/lib/carat/duckhunter.rb +158 -0
  331. data/lib/carat/dynamic-mixin.rb +71 -0
  332. data/lib/carat/enumerable-args.rb +125 -0
  333. data/lib/carat/expect.rb +192 -0
  334. data/lib/carat/filelist.rb +277 -0
  335. data/lib/carat/floatstring.rb +153 -0
  336. data/lib/carat/functor.rb +41 -0
  337. data/lib/carat/harray.rb +507 -0
  338. data/lib/carat/heap.rb +193 -0
  339. data/lib/carat/html-helpers.rb +82 -0
  340. data/lib/carat/infinity.rb +61 -0
  341. data/lib/carat/init.rb +33 -0
  342. data/lib/carat/interval.rb +248 -0
  343. data/lib/carat/io-reactor.rb +657 -0
  344. data/lib/carat/io-redirect.rb +99 -0
  345. data/lib/carat/lisp-format.rb +1832 -0
  346. data/lib/carat/lisp.rb +336 -0
  347. data/lib/carat/macro.rb +68 -0
  348. data/lib/carat/multiton.rb +153 -0
  349. data/lib/carat/nack.rb +115 -0
  350. data/lib/carat/nil-comparable.rb +67 -0
  351. data/lib/carat/nil-missing.rb +12 -0
  352. data/lib/carat/notcopyable.rb +68 -0
  353. data/lib/carat/orderedhash.rb +249 -0
  354. data/lib/carat/ostructable.rb +138 -0
  355. data/lib/carat/parser-old.rb +350 -0
  356. data/lib/carat/parser.rb +393 -0
  357. data/lib/carat/ref.rb +31 -0
  358. data/lib/carat/semaphore.rb +69 -0
  359. data/lib/carat/snapshot.rb +94 -0
  360. data/lib/carat/soundex.rb +104 -0
  361. data/lib/carat/sstruct.rb +223 -0
  362. data/lib/carat/statichash.rb +49 -0
  363. data/lib/carat/tagiter.rb +345 -0
  364. data/lib/carat/timelimit.rb +114 -0
  365. data/lib/carat/timer.rb +99 -0
  366. data/lib/carat/tracepoint.rb +154 -0
  367. data/lib/carat/tuple.rb +31 -0
  368. data/lib/carat/uninheritable.rb +68 -0
  369. data/lib/carat/version.rb +147 -0
  370. data/pub/doc/sstruct.txt +204 -0
  371. data/pub/doc/tagiter.html +145 -0
  372. data/setup.rb +1361 -0
  373. data/test/fixtures/filelist/testfile.txt +1 -0
  374. data/test/fixtures/filelist/testfile2.txt +1 -0
  375. data/test/tc_1st.rb +16 -0
  376. data/test/tc_ansicolor.rb +23 -0
  377. data/test/tc_attr.rb +46 -0
  378. data/test/tc_bbcode.rb +20 -0
  379. data/test/tc_binaryreader.rb +14 -0
  380. data/test/tc_binding_of_caller.rb +2 -0
  381. data/test/tc_byteorder.rb +41 -0
  382. data/test/tc_constant.rb +12 -0
  383. data/test/tc_coroutine.rb +50 -0
  384. data/test/tc_crosscase.rb +33 -0
  385. data/test/tc_duckhunter.rb +37 -0
  386. data/test/tc_dynamic-mixin.rb +66 -0
  387. data/test/tc_enumerable-args.rb +66 -0
  388. data/test/tc_expect.rb +83 -0
  389. data/test/tc_filelist.rb +17 -0
  390. data/test/tc_floatstring.rb +22 -0
  391. data/test/tc_functor.rb +18 -0
  392. data/test/tc_harray.rb +280 -0
  393. data/test/tc_heap.rb +6 -0
  394. data/test/tc_infinity.rb +23 -0
  395. data/test/tc_init.rb +29 -0
  396. data/test/tc_interval.rb +153 -0
  397. data/test/tc_io-reactor.rb +5 -0
  398. data/test/tc_io-redirect.rb +5 -0
  399. data/test/tc_lisp-format.rb +24 -0
  400. data/test/tc_lisp.rb +32 -0
  401. data/test/tc_macro.rb +48 -0
  402. data/test/tc_multiton.rb +188 -0
  403. data/test/tc_nack.rb +31 -0
  404. data/test/tc_nil-as-emptiness.rb +19 -0
  405. data/test/tc_nil-comparable.rb +29 -0
  406. data/test/tc_nil-missing.rb +0 -0
  407. data/test/tc_notcopyable.rb +64 -0
  408. data/test/tc_orderedhash.rb +36 -0
  409. data/test/tc_ostructable.rb +31 -0
  410. data/test/tc_semaphore.rb +5 -0
  411. data/test/tc_snapshot.rb +20 -0
  412. data/test/tc_soundex.rb +19 -0
  413. data/test/tc_sstruct.rb +313 -0
  414. data/test/tc_statichash.rb +24 -0
  415. data/test/tc_tagiter.rb +80 -0
  416. data/test/tc_timelimit.rb +47 -0
  417. data/test/tc_timer.rb +35 -0
  418. data/test/tc_tracepoint.rb +10 -0
  419. data/test/tc_tuple.rb +25 -0
  420. data/test/tc_uninheritable.rb +33 -0
  421. data/test/tc_version.rb +90 -0
  422. metadata +531 -0
@@ -0,0 +1,2 @@
1
+ 2005-01-26:
2
+ * Improved attr.rb so that #attr is now backward compatible.
data/LICENSE ADDED
@@ -0,0 +1,5 @@
1
+ OPEN SOURCE COLLECTION
2
+
3
+ A variery of open-source licenses are used.
4
+
5
+ See the license directory for all the specific licenses.
data/README ADDED
@@ -0,0 +1,67 @@
1
+ = Ruby Carats, the Ruby Toolchest
2
+
3
+ == Introduction
4
+
5
+ Ruby Carats is an extensive, 100% pure Ruby, general purposed library collection
6
+ of classes amd modules. It is an open repository for useful
7
+ general puroposed and well tested classes, modules, mixins.
8
+
9
+ == Installation
10
+
11
+ To do a manual install untar and use the included setup.rb script.
12
+
13
+ > tar -xvzf carats-x.y.z.tar.gz
14
+ > cd carats-x.y.z
15
+ > sudo ruby setup.rb
16
+
17
+ == Usage
18
+
19
+ Umm... that might require a book. You should look at the API docs.
20
+ To date, not everything in documented. But it's getting there.
21
+ You are welcome to help out. The basic require is:
22
+
23
+ require 'carat/<file>'
24
+
25
+ == Authorship
26
+
27
+ This collection was put together by, and largely written by Thomas Sawyer
28
+ (aka T. Onoma). He can be reached via email at transami at runbox.com.
29
+
30
+ This package is a collection of work by many persons.
31
+ If it matters, the collection per collection is licensed:
32
+
33
+ Ruby Carats
34
+ Copyright (c) 2004-2005 Thomas Sawyer
35
+ Ruby License
36
+
37
+ But the actual code on is licensed according to the original authors
38
+ desires, being one of the following: Ruby, GPL, LGPL, MIT, or Artistic.
39
+ Copies of these licenses should accompany this document. Any piece of code
40
+ not specifically laballed shall fall under the Ruby License.
41
+
42
+ [Please Note: I am working to make sure everything is labeled appropriately.
43
+ Please forgive me if I have not done so in a particular place --just let
44
+ me know and I will fix.]
45
+
46
+ Also, I would like to ask all those authors, whose code is collected here,
47
+ to consider moving to the Ruby license, so one license can serve for all.
48
+
49
+ === Attributed Authors
50
+
51
+ * Thomas Sawyer
52
+ * Paul Brannan
53
+ * Renald Buter
54
+ * Hal Fulton
55
+ * Gavin Sinclair
56
+ * Michael Granger
57
+ * Michael Neumann
58
+ * Florian Frank
59
+ * Mohammad Khan
60
+ * Derek Lewis
61
+ * Thomas-Ivo Heinen
62
+ * Jan Molic
63
+
64
+
65
+ == Pitch
66
+
67
+ ALL YOUR BASE ARE BELONG TO RUBY
@@ -0,0 +1,72 @@
1
+ --- %YAML:1.0
2
+
3
+ TITLE: &title Ruby Carats
4
+ NAME: &pkg carats
5
+ VERSION: '0.3.0'
6
+ AUTHOR: Trans Onoma
7
+ EMAIL: transfire@gmail.com
8
+ HOMEPAGE: "http://calibre.rubyforge.org"
9
+
10
+ SUMMARY: Collection of classes, modules, and mixins.
11
+
12
+ DESCRIPTION: >
13
+ Ruby Carats is a large collection of additions for
14
+ the Ruby programming language. Carats is broard in it
15
+ coverage and draws heavily on many works by many
16
+ authors. Ruby Carats is a subproject of Ruby Calibre.
17
+
18
+ RUBYFORGE:
19
+ PROJECT: 'calibre'
20
+ USERNAME: transami
21
+
22
+ TEST:
23
+ FILES:
24
+ - 'test/**/tc_*.rb'
25
+ OPTIONS: ~
26
+
27
+ RDOC:
28
+ TITLE: *title
29
+ DIR: 'doc'
30
+ TEMPLATE: html #ruby-red
31
+ OPTIONS: ['--merge', '--inline-source', --'all']
32
+ MAIN: README
33
+ INCLUDE:
34
+ - 'README'
35
+ - 'LICEN*'
36
+ - 'lib/carat/**/*.rb'
37
+ EXCLUDE: []
38
+
39
+ PACKAGE:
40
+ DIR: pkg
41
+ INCLUDE:
42
+ - 'lib/**/*'
43
+ - 'bench/**/*'
44
+ - 'test/**/*'
45
+ - 'rdoc/**/*'
46
+ - 'doc/**/*'
47
+ - 'pub/**/*'
48
+ - 'demo/**/*'
49
+ - 'samples/**/*'
50
+ - 'examples/**/*'
51
+ - 'setup.rb'
52
+ - '[A-Z]*'
53
+ EXCLUDE:
54
+ - InstalledFiles
55
+ ZIP: true
56
+ GZIP: true
57
+ BZIP2: true
58
+ GEM: true
59
+
60
+ ANNOUNCE:
61
+ TO: tranfire@gmail.com
62
+ FROM: transfire@gmail.com
63
+ DOMAIN: jupiterzeus.net
64
+ SERVER: gmail.com
65
+ PORT: 25
66
+ ACCOUNT: transfire@gmail.com
67
+ AUTHTYPE: plain #cram_md5
68
+ FILE: ANN
69
+ SLOGAN: ALL YOUR BASE ARE BELONG TO RUBY!
70
+ INFO:
71
+ - http://calibre.rubyforge.org
72
+
data/ToDo ADDED
@@ -0,0 +1,24 @@
1
+
2
+ - Minor:
3
+ - ordered-hash, would like an improved version.
4
+ - nil-comparable, works but I think could done better.
5
+ - lisp, there may be other places where #pair! is needed.
6
+ - interval, add infinity as possible sentinal.
7
+ - duckhunter (might be able to use Functor as decoy/probe)
8
+
9
+ - Carat-dev:
10
+ - interface
11
+ - detach
12
+
13
+ - Tests:
14
+ - binaryreader
15
+ - binding_of_caller
16
+ - coroutine, currently just checks for no error raised
17
+ - heap
18
+ - io-reactor
19
+ - io-redirect
20
+ - semaphore
21
+ - tracepoint
22
+ - 1st, needs some sort of refinement
23
+ - lisp, needs to be vastly expanded
24
+ - lisp_format, code use a few more tests
@@ -0,0 +1,49 @@
1
+ =begin
2
+
3
+ Some speed comparisions between standard Array and HArray.
4
+
5
+ =end
6
+
7
+ require 'trix/harray'
8
+ require 'benchmark'
9
+
10
+ $n = 50000
11
+
12
+ # standard array
13
+
14
+ def sarray_make
15
+ $n.times do
16
+ $sa = [1,'a',nil]
17
+ end
18
+ end
19
+
20
+ def sarray_slice
21
+ $n.times do
22
+ $sa[1..2]
23
+ end
24
+ end
25
+
26
+ # hash array
27
+
28
+ def harray_make
29
+ $n.times do
30
+ $ha = HArray.new_h({0=>1,1=>'a',2=>nil})
31
+ end
32
+ end
33
+
34
+ def harray_slice
35
+ $n.times do
36
+ $ha[1..2]
37
+ end
38
+ end
39
+
40
+
41
+ ### --- bench ---
42
+
43
+ puts "\nCURRENT"
44
+ Benchmark.bm(15) do |b|
45
+ b.report("HAarry#new:") { harray_make }
46
+ b.report("HArray#slice:") { harray_slice }
47
+ b.report("Array#new:") { sarray_make }
48
+ b.report("Array#slice:") { sarray_slice }
49
+ end
@@ -0,0 +1,64 @@
1
+
2
+ require 'benchmark'
3
+
4
+ # member?
5
+
6
+ $n = 50000
7
+
8
+ def range_nan
9
+ $n.times { ('a'..'k').member?('f') }
10
+ $n.times { ('a'..'k').member?('r') }
11
+ end
12
+
13
+ def range_small
14
+ $n.times { (0..6).member?(3) }
15
+ $n.times { (0..6).member?(7) }
16
+ end
17
+
18
+ def range_med
19
+ $n.times { (0..1000).member?(500) }
20
+ $n.times { (0..1000).member?(1001) }
21
+ end
22
+
23
+ # index
24
+
25
+ $a = [ 'x' ] * 100
26
+ $m = 500000
27
+
28
+ def range_index
29
+ i = 1
30
+ $m.times { $a[1..i]; i += 1 }
31
+ end
32
+
33
+ def length_index
34
+ i = 1
35
+ $m.times { $a[1,i]; i += 1 }
36
+ end
37
+
38
+ ### --- bench ---
39
+
40
+ puts "\nINDEXING"
41
+ Benchmark.bm(15) do |b|
42
+ b.report("range_index:") { range_index }
43
+ b.report("length_index:") { length_index }
44
+ end
45
+
46
+ puts "\n\nNew vs. Old\n"
47
+
48
+ puts "\nCURRENT"
49
+ Benchmark.bm(15) do |b|
50
+ b.report("range_nan:") { range_nan }
51
+ b.report("range_samll:") { range_small }
52
+ b.report("range_med:") { range_med }
53
+ end
54
+
55
+ puts "\nNEW"
56
+ require 'trix-dev/range/range'
57
+ Benchmark.bm(15) do |b|
58
+ b.report("range_nan:") { range_nan }
59
+ b.report("range_samll:") { range_small }
60
+ b.report("range_med:") { range_med }
61
+ end
62
+
63
+ puts
64
+
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ ## Little unix filter that colorizes diff output
4
+ #
5
+
6
+ require 'term/ansicolor'
7
+
8
+ include Term::ANSIColor
9
+
10
+ ARGF.each do |line|
11
+ print(
12
+ case line
13
+ when /^\+/ then green { line }
14
+ when /^-/ then red { line }
15
+ when /^(@@|diff)/ then blue { line }
16
+ else line
17
+ end
18
+ )
19
+ end
20
+ # vim: set et sw=2 ts=2:
@@ -0,0 +1,82 @@
1
+ require 'term/ansicolor'
2
+
3
+ # Use this trick to work around namespace cluttering that
4
+ # happens if you just include Term::ANSIColor:
5
+
6
+ class Color
7
+ class << self
8
+ include Term::ANSIColor
9
+ end
10
+ end
11
+
12
+ print Color.red, Color.bold, "No Namespace cluttering:", Color.clear, "\n"
13
+ print Color.green + "green" + Color.clear, "\n"
14
+ print Color.on_red(Color.green("green")), "\n"
15
+ print Color.yellow { Color.on_black { "yellow on_black" } }, "\n\n"
16
+
17
+ # Anyway, I don't define any of Term::ANSIColor's methods in this example
18
+ # and I want to keep it short:
19
+ include Term::ANSIColor
20
+
21
+ print red, bold, "Usage as constants:", reset, "\n"
22
+ print clear, "clear", reset, reset, "reset", reset,
23
+ bold, "bold", reset, dark, "dark", reset,
24
+ underscore, "underscore", reset, blink, "blink", reset,
25
+ negative, "negative", reset, concealed, "concealed", reset, "|\n",
26
+ black, "black", reset, red, "red", reset, green, "green", reset,
27
+ yellow, "yellow", reset, blue, "blue", reset, magenta, "magenta", reset,
28
+ cyan, "cyan", reset, white, "white", reset, "|\n",
29
+ on_black, "on_black", reset, on_red, "on_red", reset,
30
+ on_green, "on_green", reset, on_yellow, "on_yellow", reset,
31
+ on_blue, "on_blue", reset, on_magenta, "on_magenta", reset,
32
+ on_cyan, "on_cyan", reset, on_white, "on_white", reset, "|\n\n"
33
+
34
+ print red, bold, "Usage as unary functions:", reset, "\n"
35
+ print clear("clear"), reset("reset"), bold("bold"), dark("dark"),
36
+ underscore("underscore"), blink("blink"), negative("negative"),
37
+ concealed("concealed"), "|\n",
38
+ black("black"), red("red"), green("green"), yellow("yellow"),
39
+ blue("blue"), magenta("magenta"), cyan("cyan"), white("white"), "|\n",
40
+ on_black("on_black"), on_red("on_red"), on_green("on_green"),#
41
+ on_yellow("on_yellow"), on_blue("on_blue"), on_magenta("on_magenta"),
42
+ on_cyan("on_cyan"), on_white("on_white"), "|\n\n"
43
+
44
+ print red { bold { "Usage as block forms:" } }, "\n"
45
+ print clear { "clear" }, reset { "reset" }, bold { "bold" },
46
+ dark { "dark" }, underscore { "underscore" }, blink { "blink" },
47
+ negative { "negative" }, concealed { "concealed" }, "|\n",
48
+ black { "black" }, red { "red" }, green { "green" },
49
+ yellow { "yellow" }, blue { "blue" }, magenta { "magenta" },
50
+ cyan { "cyan" }, white { "white" }, "|\n",
51
+ on_black { "on_black" }, on_red { "on_red" }, on_green { "on_green" },
52
+ on_yellow { "on_yellow" }, on_blue { "on_blue" },
53
+ on_magenta { "on_magenta" }, on_cyan { "on_cyan" },
54
+ on_white { "on_white" }, "|\n\n"
55
+
56
+ # Usage as Mixin into String or its Subclasses
57
+ class String
58
+ include Term::ANSIColor
59
+ end
60
+
61
+ print "Usage as String Mixins:".red.bold, "\n"
62
+ print "clear".clear, "reset".reset, "bold".bold, "dark".dark,
63
+ "underscore".underscore, "blink".blink, "negative".negative,
64
+ "concealed".concealed, "|\n",
65
+ "black".black, "red".red, "green".green, "yellow".yellow,
66
+ "blue".blue, "magenta".magenta, "cyan".cyan, "white".white, "|\n",
67
+ "on_black".on_black, "on_red".on_red, "on_green".on_green,
68
+ "on_yellow".on_yellow, "on_blue".on_blue, "on_magenta".on_magenta,
69
+ "on_cyan".on_cyan, "on_white".on_white, "|\n\n"
70
+
71
+ symbols = Term::ANSIColor::attributes
72
+ print red { bold { "All supported attributes = " } },
73
+ blue { symbols.inspect }, "\n\n"
74
+
75
+ print "Send symbols to strings:".send(:red).send(:bold), "\n"
76
+ print symbols[12, 8].map { |c| c.to_s.send(c) }, "\n\n"
77
+
78
+ print red { bold { "Make strings monochromatic again:" } }, "\n"
79
+ print [ "red".red, "not red anymore".red.uncolored,
80
+ uncolored { "not red anymore".red }, uncolored("not red anymore".red)
81
+ ].map { |x| x + "\n" }
82
+ # vim: set et sw=2 ts=2:
@@ -0,0 +1,347 @@
1
+ #!/usr/bin/ruby
2
+ # = chatserver.rb
3
+ #
4
+ # This is an extremely crude and simple single-threaded multiplexing chat
5
+ # server. It (hopefully) demonstrates how to use a IO::Reactor object to do IO
6
+ # multiplexing with events.
7
+ #
8
+ # == Synopsis
9
+ #
10
+ # $ chatserver.rb [HOST [PORT [LOOPTIMEOUT]]]
11
+ #
12
+ # [HOST]
13
+ # The host or IP the server will bind to
14
+ #
15
+ # [PORT]
16
+ # The port the server will listen on
17
+ #
18
+ # [LOOPTIMEOUT]
19
+ # The number of floating-point seconds between polls. Specifying -1 (or any
20
+ # negative number, really) here will make the server's event loop block on the
21
+ # call to #poll.
22
+ #
23
+ # == Author
24
+ #
25
+ # Michael Granger <ged@FaerieMUD.org>
26
+ #
27
+ # Copyright (c) 2002, 2003 The FaerieMUD Consortium. All rights reserved.
28
+ #
29
+ # This program is free software. You may use, modify, and/or redistribute this
30
+ # software under the same terms as Ruby itself.
31
+ #
32
+ # This program is distributed in the hope that it will be useful, but WITHOUT
33
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
34
+ # FOR A PARTICULAR PURPOSE.
35
+ #
36
+ # == Version
37
+ #
38
+ # $Id: chatserver.rb,v 1.4 2003/08/04 23:53:32 deveiant Exp $
39
+ #
40
+
41
+ require 'io/reactor'
42
+ require 'socket'
43
+
44
+ module Example
45
+
46
+ ### Chatserver user class -- part of the chatserver example.
47
+ class User
48
+
49
+ MTU = 4096
50
+ CR = "\015"
51
+ LF = "\012"
52
+ EOL = CR + LF
53
+
54
+ PROMPT = 'chat> '
55
+
56
+ ### Create and return a user object which will use the specified
57
+ ### <tt>socket</tt> and <tt>pollObj</tt>.
58
+ def initialize( socket, server )
59
+ @socket = socket
60
+ @server = server
61
+ @obuffer = ''
62
+ @ibuffer = ''
63
+ @peerHost = @socket.peeraddr[2]
64
+ @peerPort = @socket.peeraddr[1]
65
+ @connected = true
66
+ end
67
+
68
+ # Object attribute
69
+ attr_reader :socket, :server, :ibuffer, :obuffer
70
+
71
+
72
+ ### Return a stringified version of the user
73
+ def to_s
74
+ "%s:%d" % [ @peerHost, @peerPort ]
75
+ end
76
+
77
+
78
+ ### Add the specified string to the user's output buffer and turn on
79
+ ### output events.
80
+ def addOutput( string )
81
+ @obuffer << string.chomp << EOL
82
+ @server.reactor.enableEvents( @socket, :write )
83
+ end
84
+ alias :<< :addOutput
85
+
86
+
87
+ ### Write as much of the output buffer to the socket as possible, and return
88
+ ### the number of bytes remaining to be sent.
89
+ def writeOutput
90
+ bytes = @socket.syswrite( @obuffer )
91
+ @obuffer[ 0, bytes ] = '' if bytes.nonzero?
92
+ return @obuffer.length
93
+ end
94
+
95
+
96
+ ### Write a prompt to the user
97
+ def prompt
98
+ @obuffer << PROMPT
99
+ @server.reactor.enableEvents( @socket, :write )
100
+ end
101
+
102
+
103
+ ### Read at most MTU bytes from the socket and append them to the input
104
+ ### buffer. Split off any complete lines (one that end with EOL) and return
105
+ ### them as an Array of Strings.
106
+ def readInput
107
+ rary = []
108
+ @ibuffer << @socket.sysread( MTU )
109
+ $stderr.puts "Input buffer for user #{self} now: #@ibuffer" if $VERBOSE
110
+ while (( pos = @ibuffer.index EOL ))
111
+ $stderr.puts "Found terminating EOL. "\
112
+ "Splitting off 0..#{pos} of the input buffer." if $VERBOSE
113
+ rary << @ibuffer[ 0, pos ]
114
+ @ibuffer[ 0, pos + EOL.length ] = ''
115
+ end
116
+
117
+ return rary
118
+ rescue EOFError
119
+ @server.disconnectUser( self )
120
+ return []
121
+ end
122
+
123
+
124
+ ### Handle poll events on the socket
125
+ def handleIOEvent( io, event )
126
+ case event
127
+
128
+ when :error
129
+ @server.disconnectUser( self )
130
+
131
+ when :read
132
+ input = readInput()
133
+ @server.processInput( self, *input ) unless input.empty?
134
+
135
+ when :write
136
+ bytesLeft = writeOutput()
137
+ @server.reactor.disableEvents( @socket, :write ) if bytesLeft.zero?
138
+
139
+ end
140
+
141
+ end
142
+
143
+
144
+ ### Disconnect the user
145
+ def disconnect( msg='' )
146
+ @connected = false
147
+ unless msg.empty?
148
+ @obuffer = ">>> Disconnected: #{msg} <<<" + EOL
149
+ else
150
+ @obuffer = ">>> Disconnected <<<" + EOL
151
+ end
152
+ writeOutput()
153
+ @socket.close
154
+ end
155
+
156
+
157
+ ### Returns true if the user is still connected
158
+ def connected?
159
+ @connected
160
+ end
161
+ end # class User
162
+
163
+
164
+ ### Example chatserver class -- an extremely crude and simple chat server that
165
+ ### demonstrates how to use Poll to do multiplexing IO in a single thread.
166
+ class Server
167
+
168
+ BANNER = <<-EOF
169
+ [[ IO::Reactor Example Chatserver ]]
170
+ Commands: '/quit' to quit, '/shutdown' to shut the server down
171
+ EOF
172
+
173
+ ### Instantiate and return a chatserver on the specified host and port
174
+ def initialize( listenHost="0.0.0.0", listenPort=1138, interval=0.20 )
175
+ @socket = TCPServer::new( listenHost, listenPort )
176
+ @users = []
177
+ @reactor = IO::Reactor::new
178
+ @pollInterval = interval
179
+ @shuttingDown = false
180
+
181
+ @reactor.register @socket, :read, &method(:handlePollEvent)
182
+ end
183
+
184
+ # Server attributes
185
+ attr_reader :reactor, :users, :socket
186
+
187
+
188
+ ### Main server loop
189
+ def eventLoop
190
+ trap( "INT" ) { shutdown("Server caught SIGINT") }
191
+ trap( "TERM" ) { shutdown("Server caught SIGTERM") }
192
+ trap( "HUP" ) { disconnectAllUsers(">>> Server reset <<<") }
193
+
194
+ until @shuttingDown
195
+ eventCount = @reactor.poll( @pollInterval )
196
+ end
197
+
198
+ rescue StandardError => e
199
+ $stderr.puts "Error in server: #{e.message}"
200
+ $stderr.puts "\t" + e.backtrace.join( "\n\t" )
201
+ shutdown( "Server error: #{e.message}" )
202
+ rescue SignalException => e
203
+ shutdown( "Server caught #{e.type.name}" )
204
+ ensure
205
+ trap( "INT", "SIG_IGN" )
206
+ trap( "TERM", "SIG_IGN" )
207
+ trap( "HUP", "SIG_IGN" )
208
+
209
+ $stderr.puts "Server exiting event loop."
210
+ end
211
+
212
+
213
+ ### Handle a poll event specified by <tt>event</tt> on the specified
214
+ ### <tt>socket</tt>
215
+ def handlePollEvent( socket, event )
216
+ $stderr.puts "Got #{event.inspect} event for #{socket.inspect}"
217
+
218
+ case event
219
+ when :error
220
+ $stderr.puts "Socket error on the listener socket."
221
+ shutdown()
222
+
223
+ when :read
224
+ clSock = socket.accept
225
+ user = User::new( clSock, self )
226
+ $stderr.puts "Accepted connection from #{user}"
227
+ @reactor.register clSock, :read, &user.method(:handleIOEvent)
228
+ user.addOutput( BANNER )
229
+ user.prompt
230
+ broadcastMsg( "[New connection: #{user}]" )
231
+ @users << user
232
+
233
+ end
234
+ end
235
+
236
+
237
+ ### Process the specified input from the specified user
238
+ def processInput( user, *inputStrings )
239
+ inputStrings.each {|str|
240
+ case str
241
+
242
+ when %r{^/(\w+)\s*(.*)}
243
+ handleCommand( user, $1, $2 )
244
+
245
+ else
246
+ user.addOutput( "You>> #{str}" )
247
+ broadcastMsgFrom( user, str )
248
+ end
249
+ }
250
+
251
+ user.prompt if user.connected?
252
+ end
253
+
254
+
255
+ ### Handle the specified command from the specified user
256
+ def handleCommand( user, command, args )
257
+ case command
258
+
259
+ when /quit/
260
+ disconnectUser( user, 'Quit' )
261
+
262
+ when /shutdown/
263
+ shutdown()
264
+
265
+ when /who/
266
+ user.addOutput( self.wholist(user) )
267
+
268
+ else
269
+ user.addOutput("Unknown command '#{command}'")
270
+ end
271
+ end
272
+
273
+
274
+ ### Broadcast the specified message to all connected users
275
+ def broadcastMsg( msg )
276
+ @users.each {|cl|
277
+ cl.addOutput( msg )
278
+ }
279
+ end
280
+
281
+
282
+ ### Broadcast the specified message from the specified user
283
+ def broadcastMsgFrom( user, msg )
284
+ userDesc = user.to_s
285
+
286
+ @users.each {|cl|
287
+ next if cl == user
288
+ cl.addOutput( "#{userDesc}>> #{msg}" )
289
+ }
290
+ end
291
+
292
+
293
+ ### Disconnect the specified user
294
+ def disconnectUser( user, msg='' )
295
+ @users -= [ user ]
296
+ @reactor.unregister( user.socket )
297
+ user.disconnect( msg )
298
+ broadcastMsg( "#{user.to_s} Disconnected." )
299
+ end
300
+
301
+
302
+ ### Disconnect all connected users
303
+ def disconnectAllUsers( msg )
304
+ @users.each {|user|
305
+ @reactor.unregister( user.socket )
306
+ user.disconnect( msg )
307
+ }
308
+ @users.clear
309
+ end
310
+
311
+
312
+ ### Shut the server down
313
+ def shutdown( msg="Server shutdown" )
314
+ $stderr.puts "Shutting down: #{msg}"
315
+ @shuttingDown = true
316
+ @reactor.clear
317
+ begin
318
+ @socket.shutdown
319
+ rescue
320
+ end
321
+ disconnectAllUsers( msg )
322
+ begin
323
+ @socket.close
324
+ rescue
325
+ end
326
+ end
327
+
328
+ ### Build and return a list of connected users for the specified user.
329
+ def wholist( user )
330
+ rval = "[Connected Users]\n" <<
331
+ " *#{user}*\n"
332
+ @users.each {|u|
333
+ next if u == user
334
+ rval << " #{u}\n"
335
+ }
336
+
337
+ return rval
338
+ end
339
+
340
+ end # class Server
341
+ end # module Example
342
+
343
+ srv = Example::Server::new( *ARGV )
344
+ $stderr.puts "Chat server listening on #{srv.socket.addr[2]} port #{srv.socket.addr[1]}"
345
+ srv.eventLoop
346
+ $stderr.puts "Chat server finished."
347
+