opal 0.2.2 → 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 (325) hide show
  1. data/.gitignore +5 -10
  2. data/LICENSE +75 -0
  3. data/README.md +55 -3
  4. data/Rakefile +62 -139
  5. data/bin/opal +7 -10
  6. data/gems/core/README.md +5 -0
  7. data/gems/core/Rakefile +7 -0
  8. data/gems/core/core.gemspec +13 -0
  9. data/gems/core/lib/core.rb +33 -0
  10. data/gems/core/lib/core/array.rb +1470 -0
  11. data/gems/core/lib/core/basic_object.rb +15 -0
  12. data/gems/core/lib/core/class.rb +31 -0
  13. data/gems/core/lib/core/dir.rb +26 -0
  14. data/gems/core/lib/core/error.rb +43 -0
  15. data/gems/core/lib/core/false_class.rb +21 -0
  16. data/gems/core/lib/core/file.rb +54 -0
  17. data/gems/core/lib/core/hash.rb +725 -0
  18. data/gems/core/lib/core/kernel.rb +240 -0
  19. data/gems/core/lib/core/module.rb +98 -0
  20. data/gems/core/lib/core/nil_class.rb +41 -0
  21. data/gems/core/lib/core/numeric.rb +370 -0
  22. data/gems/core/lib/core/proc.rb +11 -0
  23. data/gems/core/lib/core/range.rb +17 -0
  24. data/gems/core/lib/core/regexp.rb +18 -0
  25. data/gems/core/lib/core/string.rb +328 -0
  26. data/gems/core/lib/core/symbol.rb +15 -0
  27. data/gems/core/lib/core/top_self.rb +8 -0
  28. data/gems/core/lib/core/true_class.rb +20 -0
  29. data/gems/core/lib/core/vm.rb +16 -0
  30. data/{opals/opal/opal → gems/core}/spec/core/array/append_spec.rb +0 -0
  31. data/{opals/opal/opal → gems/core}/spec/core/array/assoc_spec.rb +0 -0
  32. data/{opals/opal/opal → gems/core}/spec/core/array/at_spec.rb +0 -0
  33. data/{opals/opal/opal → gems/core}/spec/core/array/clear_spec.rb +1 -1
  34. data/{opals/opal/opal → gems/core}/spec/core/array/collect_bang_spec.rb +0 -0
  35. data/{opals/opal/opal → gems/core}/spec/core/array/collect_spec.rb +0 -0
  36. data/gems/core/spec/core/array/compact_spec.rb +41 -0
  37. data/{opals/opal/opal → gems/core}/spec/core/array/concat_spec.rb +0 -0
  38. data/{opals/opal/opal → gems/core}/spec/core/array/constructor_spec.rb +0 -0
  39. data/{opals/opal/opal → gems/core}/spec/core/array/each_spec.rb +0 -0
  40. data/{opals/opal/opal → gems/core}/spec/core/array/element_reference_spec.rb +0 -0
  41. data/{opals/opal/opal → gems/core}/spec/core/array/first_spec.rb +1 -1
  42. data/{opals/opal/opal → gems/core}/spec/core/array/include_spec.rb +0 -0
  43. data/gems/core/spec/core/array/join_spec.rb +6 -0
  44. data/gems/core/spec/core/array/last_spec.rb +51 -0
  45. data/gems/core/spec/core/array/length_spec.rb +6 -0
  46. data/{opals/opal/opal → gems/core}/spec/core/array/map_spec.rb +2 -0
  47. data/gems/core/spec/core/array/reverse_spec.rb +6 -0
  48. data/{opals/opal/opal → gems/core}/spec/core/builtin_constants/builtin_constants_spec.rb +0 -0
  49. data/{opals/opal/opal → gems/core}/spec/core/false/and_spec.rb +0 -0
  50. data/{opals/opal/opal → gems/core}/spec/core/false/inspect_spec.rb +0 -0
  51. data/{opals/opal/opal → gems/core}/spec/core/false/or_spec.rb +0 -0
  52. data/{opals/opal/opal → gems/core}/spec/core/false/to_s_spec.rb +0 -0
  53. data/{opals/opal/opal → gems/core}/spec/core/false/xor_spec.rb +0 -0
  54. data/{opals/opal/opal → gems/core}/spec/core/file/join_spec.rb +1 -1
  55. data/gems/core/spec/core/hash/assoc_spec.rb +32 -0
  56. data/{opals/opal/opal → gems/core}/spec/core/kernel/instance_eval_spec.rb +0 -0
  57. data/{opals/opal/opal → gems/core}/spec/core/kernel/loop_spec.rb +0 -0
  58. data/{opals/opal/opal → gems/core}/spec/core/kernel/raise_spec.rb +0 -0
  59. data/{opals/opal/opal → gems/core}/spec/core/module/attr_accessor_spec.rb +0 -0
  60. data/{opals/opal/opal → gems/core}/spec/core/number/lt_spec.rb +0 -0
  61. data/gems/core/spec/core/string/sub_spec.rb +24 -0
  62. data/{opals/opal/opal → gems/core}/spec/core/true/and_spec.rb +0 -0
  63. data/{opals/opal/opal → gems/core}/spec/core/true/inspect_spec.rb +0 -0
  64. data/{opals/opal/opal → gems/core}/spec/core/true/or_spec.rb +0 -0
  65. data/{opals/opal/opal → gems/core}/spec/core/true/to_s_spec.rb +0 -0
  66. data/{opals/opal/opal → gems/core}/spec/core/true/xor_spec.rb +0 -0
  67. data/{opals/opal/opal → gems/core}/spec/language/and_spec.rb +2 -3
  68. data/{opals/opal/opal → gems/core}/spec/language/array_spec.rb +21 -5
  69. data/gems/core/spec/language/block_spec.rb +38 -0
  70. data/{opals/opal/opal → gems/core}/spec/language/break_spec.rb +0 -0
  71. data/gems/core/spec/language/case_spec.rb +103 -0
  72. data/{opals/opal/opal → gems/core}/spec/language/def_spec.rb +11 -1
  73. data/{opals/opal/opal → gems/core}/spec/language/eigenclass_spec.rb +0 -0
  74. data/gems/core/spec/language/file_spec.rb +13 -0
  75. data/gems/core/spec/language/fixtures/block.rb +21 -0
  76. data/gems/core/spec/language/fixtures/super.rb +293 -0
  77. data/{opals/opal/opal → gems/core}/spec/language/hash_spec.rb +0 -0
  78. data/{opals/opal/opal → gems/core}/spec/language/if_spec.rb +0 -0
  79. data/{opals/opal/opal → gems/core}/spec/language/loop_spec.rb +0 -0
  80. data/gems/core/spec/language/metaclass_spec.rb +21 -0
  81. data/{opals/opal/opal → gems/core}/spec/language/method_spec.rb +60 -0
  82. data/{opals/opal/opal → gems/core}/spec/language/next_spec.rb +0 -0
  83. data/{opals/opal/opal → gems/core}/spec/language/or_spec.rb +0 -0
  84. data/{opals/opal/opal → gems/core}/spec/language/redo_spec.rb +0 -0
  85. data/gems/core/spec/language/regexp_spec.rb +26 -0
  86. data/{opals/opal/opal → gems/core}/spec/language/rescue_spec.rb +0 -0
  87. data/{opals/opal/opal → gems/core}/spec/language/return_spec.rb +0 -0
  88. data/{opals/opal/opal → gems/core}/spec/language/string_spec.rb +0 -0
  89. data/gems/core/spec/language/super_spec.rb +32 -0
  90. data/{opals/opal/opal → gems/core}/spec/language/until_spec.rb +47 -47
  91. data/gems/core/spec/language/variables_spec.rb +155 -0
  92. data/{opals/opal/opal → gems/core}/spec/language/while_spec.rb +47 -47
  93. data/{opals/opal/opal → gems/core}/spec/spec_helper.rb +1 -1
  94. data/gems/core_fs/README.md +19 -0
  95. data/gems/dev/Rakefile +5 -0
  96. data/gems/dev/lib/dev.js +99 -0
  97. data/gems/dev/lib/dev/generator.js +1264 -0
  98. data/gems/dev/lib/dev/parser.js +979 -0
  99. data/gems/dev/lib/dev/ruby_parser.js +1088 -0
  100. data/gems/dev/lib/dev/ruby_parser.y +1267 -0
  101. data/gems/dev/lib/dev/string_scanner.js +38 -0
  102. data/gems/dev/tools/racc2js/README.md +39 -0
  103. data/gems/dev/tools/racc2js/math_parser.js +222 -0
  104. data/gems/dev/tools/racc2js/math_parser.rb +133 -0
  105. data/gems/dev/tools/racc2js/math_parser.y +28 -0
  106. data/gems/dev/tools/racc2js/parser.js +218 -0
  107. data/gems/dev/tools/racc2js/racc2js.rb +153 -0
  108. data/gems/json/README.md +4 -0
  109. data/gems/json/json.gemspec +14 -0
  110. data/gems/json/lib/json.rb +64 -0
  111. data/gems/json/lib/json/ext.rb +51 -0
  112. data/{opals/opal/browser/lib/browser/json_parse.js → gems/json/lib/json/json2.js} +197 -37
  113. data/gems/ospec/README.md +0 -0
  114. data/gems/ospec/lib/ospec.rb +6 -0
  115. data/gems/ospec/lib/ospec/autorun.rb +3 -0
  116. data/gems/ospec/lib/ospec/dsl.rb +15 -0
  117. data/gems/ospec/lib/ospec/example.rb +11 -0
  118. data/gems/ospec/lib/ospec/example/before_and_after_hooks.rb +56 -0
  119. data/gems/ospec/lib/ospec/example/errors.rb +17 -0
  120. data/gems/ospec/lib/ospec/example/example_group.rb +12 -0
  121. data/gems/ospec/lib/ospec/example/example_group_factory.rb +21 -0
  122. data/gems/ospec/lib/ospec/example/example_group_hierarchy.rb +20 -0
  123. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/example/example_group_methods.rb +26 -68
  124. data/gems/ospec/lib/ospec/example/example_group_proxy.rb +14 -0
  125. data/gems/ospec/lib/ospec/example/example_methods.rb +46 -0
  126. data/gems/ospec/lib/ospec/example/example_proxy.rb +18 -0
  127. data/gems/ospec/lib/ospec/expectations.rb +19 -0
  128. data/gems/ospec/lib/ospec/expectations/errors.rb +8 -0
  129. data/gems/ospec/lib/ospec/expectations/fail_with.rb +8 -0
  130. data/gems/ospec/lib/ospec/expectations/handler.rb +27 -0
  131. data/gems/ospec/lib/ospec/matchers.rb +24 -0
  132. data/{opals/opal/Rakefile → gems/ospec/lib/ospec/matchers/be.rb} +0 -0
  133. data/gems/ospec/lib/ospec/matchers/generated_descriptions.rb +20 -0
  134. data/gems/ospec/lib/ospec/matchers/operator_matcher.rb +52 -0
  135. data/gems/ospec/lib/ospec/runner.rb +40 -0
  136. data/gems/ospec/lib/ospec/runner/example_group_runner.rb +44 -0
  137. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/runner/formatter/html_formatter.rb +31 -40
  138. data/gems/ospec/lib/ospec/runner/formatter/terminal_formatter.rb +48 -0
  139. data/gems/ospec/lib/ospec/runner/options.rb +36 -0
  140. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/runner/reporter.rb +23 -55
  141. data/gems/ospec/ospec.gemspec +0 -0
  142. data/gems/rquery/README.md +9 -0
  143. data/gems/rquery/lib/rquery.rb +10 -0
  144. data/gems/rquery/lib/rquery/ajax.rb +4 -0
  145. data/gems/rquery/lib/rquery/css.rb +96 -0
  146. data/gems/rquery/lib/rquery/document.rb +25 -0
  147. data/gems/rquery/lib/rquery/element.rb +292 -0
  148. data/gems/rquery/lib/rquery/event.rb +108 -0
  149. data/gems/rquery/lib/rquery/jquery.js +8177 -0
  150. data/gems/rquery/lib/rquery/request.rb +138 -0
  151. data/gems/rquery/lib/rquery/response.rb +49 -0
  152. data/gems/rquery/rquery.gemspec +16 -0
  153. data/lib/opal.js +1597 -0
  154. data/lib/opal.rb +6 -69
  155. data/lib/opal/builder.rb +115 -0
  156. data/lib/opal/bundle.rb +131 -0
  157. data/lib/opal/command.rb +11 -0
  158. data/lib/opal/context.rb +69 -0
  159. data/lib/opal/context/console.rb +12 -0
  160. data/lib/opal/context/file_system.rb +19 -0
  161. data/lib/opal/context/loader.rb +117 -0
  162. data/lib/opal/gem.rb +153 -0
  163. data/lib/opal/ruby/nodes.rb +1302 -0
  164. data/lib/opal/ruby/parser.rb +780 -0
  165. data/lib/opal/ruby/ruby_parser.rb +5170 -0
  166. data/lib/opal/ruby/ruby_parser.y +1298 -0
  167. data/opal.gemspec +11 -256
  168. metadata +179 -240
  169. data/.gitmodules +0 -6
  170. data/Opalfile +0 -384
  171. data/VERSION +0 -1
  172. data/demos/apps/browser_demo/index.html +0 -11
  173. data/demos/apps/browser_demo/lib/browser_demo.rb +0 -31
  174. data/demos/apps/simple_opal/Opalfile +0 -13
  175. data/demos/apps/simple_opal/index.html +0 -11
  176. data/demos/apps/simple_opal/lib/app_controller.rb +0 -62
  177. data/demos/apps/simple_opal/lib/main_window.rb +0 -146
  178. data/demos/browser/request/index.html +0 -52
  179. data/demos/browser/request/request.rb +0 -48
  180. data/gen/browser/__PROJECT_NAME__/Rakefile +0 -12
  181. data/gen/browser/__PROJECT_NAME__/index.html +0 -11
  182. data/gen/browser/__PROJECT_NAME__/javascripts/opal.debug.js +0 -4687
  183. data/gen/browser/__PROJECT_NAME__/javascripts/opal.min.js +0 -175
  184. data/gen/browser/__PROJECT_NAME__/lib/__PROJECT_NAME__.rb +0 -1
  185. data/lib/opal/builders/base.rb +0 -50
  186. data/lib/opal/builders/css.rb +0 -46
  187. data/lib/opal/builders/javascript.rb +0 -44
  188. data/lib/opal/builders/opal.rb +0 -79
  189. data/lib/opal/builders/ruby.rb +0 -50
  190. data/lib/opal/builders/ruby/generate.rb +0 -1851
  191. data/lib/opal/builders/ruby/nodes.rb +0 -210
  192. data/lib/opal/builders/ruby/ruby.rb +0 -916
  193. data/lib/opal/builders/ruby/ruby_parser.rb +0 -6008
  194. data/lib/opal/builders/ruby/ruby_parser.rb.y +0 -1451
  195. data/lib/opal/models/build_item.rb +0 -104
  196. data/lib/opal/models/hash_struct.rb +0 -40
  197. data/lib/opal/models/project.rb +0 -252
  198. data/lib/opal/models/struct_accessors.rb +0 -58
  199. data/lib/opal/models/target.rb +0 -176
  200. data/lib/opal/opal/build.rb +0 -169
  201. data/lib/opal/opal/env/console.rb +0 -66
  202. data/lib/opal/opal/env/fs.rb +0 -98
  203. data/lib/opal/opal/env/object.rb +0 -48
  204. data/lib/opal/opal/environment.rb +0 -139
  205. data/lib/opal/opal/gen.rb +0 -62
  206. data/lib/opal/opal/opal.rb +0 -75
  207. data/lib/opal/opal/repl.rb +0 -38
  208. data/lib/opal/opalfile/dsl.rb +0 -62
  209. data/lib/opal/opalfile/opalfile.rb +0 -133
  210. data/lib/opal/opalfile/task.rb +0 -96
  211. data/lib/opal/opalfile/task_manager.rb +0 -63
  212. data/lib/opal/opalfile/task_scope.rb +0 -52
  213. data/lib/opal/rack/app_server.rb +0 -119
  214. data/lib/opal/rake/opal_task.rb +0 -34
  215. data/opals/opal/README.md +0 -37
  216. data/opals/opal/browser/Opalfile +0 -11
  217. data/opals/opal/browser/README.md +0 -146
  218. data/opals/opal/browser/SIZZLE_LICESNSE.txt +0 -148
  219. data/opals/opal/browser/lib/browser.rb +0 -118
  220. data/opals/opal/browser/lib/browser/builder.rb +0 -41
  221. data/opals/opal/browser/lib/browser/canvas_context.rb +0 -115
  222. data/opals/opal/browser/lib/browser/dimensions.rb +0 -50
  223. data/opals/opal/browser/lib/browser/document.rb +0 -146
  224. data/opals/opal/browser/lib/browser/element.rb +0 -487
  225. data/opals/opal/browser/lib/browser/element/attributes.rb +0 -88
  226. data/opals/opal/browser/lib/browser/element/css.rb +0 -290
  227. data/opals/opal/browser/lib/browser/element/form.rb +0 -146
  228. data/opals/opal/browser/lib/browser/event/dom_events.rb +0 -81
  229. data/opals/opal/browser/lib/browser/event/event.rb +0 -177
  230. data/opals/opal/browser/lib/browser/event/trigger_events.rb +0 -53
  231. data/opals/opal/browser/lib/browser/geometry.rb +0 -97
  232. data/opals/opal/browser/lib/browser/json.rb +0 -32
  233. data/opals/opal/browser/lib/browser/request/request.rb +0 -201
  234. data/opals/opal/browser/lib/browser/sizzle.js +0 -1068
  235. data/opals/opal/browser/lib/browser/string.rb +0 -42
  236. data/opals/opal/browser/lib/browser/touch.rb +0 -37
  237. data/opals/opal/browser/lib/browser/vml_context.js +0 -33
  238. data/opals/opal/browser/lib/browser/window.rb +0 -36
  239. data/opals/opal/browser/spec/browser/browser_detection_spec.rb +0 -7
  240. data/opals/opal/browser/spec/document/aref_spec.rb +0 -110
  241. data/opals/opal/browser/spec/document/ready_spec.rb +0 -16
  242. data/opals/opal/browser/spec/element/body_spec.rb +0 -11
  243. data/opals/opal/browser/spec/element/clear_spec.rb +0 -26
  244. data/opals/opal/browser/spec/element/empty_spec.rb +0 -29
  245. data/opals/opal/browser/spec/element/has_class_spec.rb +0 -40
  246. data/opals/opal/browser/spec/element/hidden_spec.rb +0 -23
  247. data/opals/opal/browser/spec/element/hide_spec.rb +0 -31
  248. data/opals/opal/browser/spec/element/remove_spec.rb +0 -25
  249. data/opals/opal/browser/spec/element/show_spec.rb +0 -31
  250. data/opals/opal/browser/spec/element/style_spec.rb +0 -69
  251. data/opals/opal/browser/spec/element/toggle_spec.rb +0 -31
  252. data/opals/opal/browser/spec/element/visible_spec.rb +0 -23
  253. data/opals/opal/browser/spec/spec_helper.rb +0 -1
  254. data/opals/opal/opal/Opalfile +0 -14
  255. data/opals/opal/opal/spec/core/array/compact_spec.rb +0 -15
  256. data/opals/opal/opal/spec/fixtures/super.rb +0 -70
  257. data/opals/opal/opal/spec/language/____temp_remove_this.rb +0 -12
  258. data/opals/opal/opal/spec/language/block_spec.rb +0 -18
  259. data/opals/opal/opal/spec/language/case_spec.rb +0 -103
  260. data/opals/opal/opal/spec/language/metaclass_spec.rb +0 -21
  261. data/opals/opal/opal/spec/language/super_spec.rb +0 -26
  262. data/opals/opal/runtime/Opalfile +0 -78
  263. data/opals/opal/runtime/README.md +0 -12
  264. data/opals/opal/runtime/docs/debugging.md +0 -51
  265. data/opals/opal/runtime/lib/array.rb +0 -1516
  266. data/opals/opal/runtime/lib/basic_object.rb +0 -49
  267. data/opals/opal/runtime/lib/class.rb +0 -54
  268. data/opals/opal/runtime/lib/dir.rb +0 -36
  269. data/opals/opal/runtime/lib/error.rb +0 -49
  270. data/opals/opal/runtime/lib/false_class.rb +0 -52
  271. data/opals/opal/runtime/lib/file.rb +0 -79
  272. data/opals/opal/runtime/lib/hash.rb +0 -791
  273. data/opals/opal/runtime/lib/io.rb +0 -39
  274. data/opals/opal/runtime/lib/kernel.rb +0 -288
  275. data/opals/opal/runtime/lib/match_data.rb +0 -36
  276. data/opals/opal/runtime/lib/module.rb +0 -109
  277. data/opals/opal/runtime/lib/nil_class.rb +0 -69
  278. data/opals/opal/runtime/lib/number.rb +0 -398
  279. data/opals/opal/runtime/lib/proc.rb +0 -77
  280. data/opals/opal/runtime/lib/range.rb +0 -63
  281. data/opals/opal/runtime/lib/regexp.rb +0 -111
  282. data/opals/opal/runtime/lib/ruby.rb +0 -30
  283. data/opals/opal/runtime/lib/string.rb +0 -328
  284. data/opals/opal/runtime/lib/symbol.rb +0 -40
  285. data/opals/opal/runtime/lib/top_self.rb +0 -33
  286. data/opals/opal/runtime/lib/true_class.rb +0 -45
  287. data/opals/opal/runtime/runtime/browser.js +0 -287
  288. data/opals/opal/runtime/runtime/debug.js +0 -180
  289. data/opals/opal/runtime/runtime/opal.js +0 -1008
  290. data/opals/opal/runtime/runtime/post_opal.js +0 -1
  291. data/opals/opal/runtime/runtime/pre_opal.js +0 -2
  292. data/opals/opal/runtime/runtime/server_side.js +0 -50
  293. data/opals/opal/spec/LICENSE.txt +0 -26
  294. data/opals/opal/spec/Opalfile +0 -5
  295. data/opals/opal/spec/bin/spec.rb +0 -43
  296. data/opals/opal/spec/lib/spec.rb +0 -33
  297. data/opals/opal/spec/lib/spec/dsl.rb +0 -41
  298. data/opals/opal/spec/lib/spec/example.rb +0 -35
  299. data/opals/opal/spec/lib/spec/example/before_and_after_hooks.rb +0 -81
  300. data/opals/opal/spec/lib/spec/example/errors.rb +0 -42
  301. data/opals/opal/spec/lib/spec/example/example_group.rb +0 -37
  302. data/opals/opal/spec/lib/spec/example/example_group_factory.rb +0 -43
  303. data/opals/opal/spec/lib/spec/example/example_group_hierarchy.rb +0 -45
  304. data/opals/opal/spec/lib/spec/example/example_group_proxy.rb +0 -41
  305. data/opals/opal/spec/lib/spec/example/example_methods.rb +0 -73
  306. data/opals/opal/spec/lib/spec/example/example_proxy.rb +0 -48
  307. data/opals/opal/spec/lib/spec/expectations.rb +0 -46
  308. data/opals/opal/spec/lib/spec/expectations/errors.rb +0 -35
  309. data/opals/opal/spec/lib/spec/expectations/fail_with.rb +0 -37
  310. data/opals/opal/spec/lib/spec/expectations/handler.rb +0 -48
  311. data/opals/opal/spec/lib/spec/matchers.rb +0 -50
  312. data/opals/opal/spec/lib/spec/matchers/be.rb +0 -26
  313. data/opals/opal/spec/lib/spec/matchers/generated_descriptions.rb +0 -47
  314. data/opals/opal/spec/lib/spec/matchers/operator_matcher.rb +0 -66
  315. data/opals/opal/spec/lib/spec/runner.rb +0 -48
  316. data/opals/opal/spec/lib/spec/runner/example_group_runner.rb +0 -71
  317. data/opals/opal/spec/lib/spec/runner/formatter/terminal_formatter.rb +0 -82
  318. data/opals/opal/spec/lib/spec/runner/options.rb +0 -63
  319. data/opals/opal/spec/resources/index.html +0 -25
  320. data/opals/opal/spec/resources/spec.css +0 -132
  321. data/spec/cherry_kit/iseq_spec.rb +0 -38
  322. data/spec/spec_helper.rb +0 -16
  323. data/spec/vienna_spec.rb +0 -7
  324. data/yard/index.html +0 -43
  325. data/yard/style.css +0 -765
@@ -0,0 +1,1470 @@
1
+ # Arrays are ordered, indexed by integers starting at 0
2
+ #
3
+ # Implementation details
4
+ # ======================
5
+ #
6
+ # For efficiency, an array instance is simply a native javascript array. There
7
+ # is no wrapping, it is simply a toll-free class
8
+ class Array
9
+ # Returns a new array populated with the given objects.
10
+ #
11
+ # @example
12
+ #
13
+ # Array['a', 'b', 'c']
14
+ # # => ['a', 'b', 'c']
15
+ #
16
+ # FIXME should support custom subclasses
17
+ #
18
+ # @param [Object] objs
19
+ # @return [Array]
20
+ def self.[](*objs)
21
+ objs
22
+ end
23
+
24
+ # FIXME should support custom subclasses
25
+ def self.allocate
26
+ []
27
+ end
28
+
29
+ def initialize(*objs)
30
+ `for (var i = 0, length = objs.length; i < length; i++) {
31
+ self.push(objs[i]);
32
+ }
33
+
34
+ return self;`
35
+ end
36
+
37
+ # Returns a formatted, printable version of the array. {#inspect} is called
38
+ # on each of the elements and appended to the string.
39
+ #
40
+ # @return [String] string representation of the receiver
41
+ def inspect
42
+ `var description = [];
43
+
44
+ for (var i = 0, length = self.length; i < length; i++) {
45
+ description.push(#{`self[i]`.inspect});
46
+ }
47
+
48
+ return '[' + description.join(', ') + ']';`
49
+ end
50
+
51
+ # Returns a simple string version of the array. {#to_s} is applied to each
52
+ # of the child elements with no seperator.
53
+ def to_s
54
+ `var description = [];
55
+
56
+ for (var i = 0, length = self.length; i < length; i++) {
57
+ description.push(#{`self[i]`.to_s});
58
+ }
59
+
60
+ return description.join('');`
61
+ end
62
+
63
+ # Append - pushes the given object onto the end of this array. This
64
+ # expression returns the array itself, so several appends may be chained
65
+ # together.
66
+ #
67
+ # @example
68
+ #
69
+ # [1, 2] << "c" << "d" << [3, 4]
70
+ # # => [1, 2, "c", "d", [3, 4]]
71
+ #
72
+ # @param [Object] obj the object to append
73
+ # @return [Array] returns the receiver
74
+ def <<(obj)
75
+ `self.push(obj);`
76
+ self
77
+ end
78
+
79
+ # Returns the number of elements in `self`. May be zero.
80
+ #
81
+ # @example
82
+ #
83
+ # [1, 2, 3, 4, 5].length
84
+ # # => 5
85
+ #
86
+ # @return [Numeric] length
87
+ def length
88
+ `return self.length;`
89
+ end
90
+
91
+ def size
92
+ `return self.length;`
93
+ end
94
+
95
+ # Yields the block once for each element in `self`, passing that element as
96
+ # a parameter.
97
+ #
98
+ # If no block is given, an enumerator is returned instead.
99
+ #
100
+ # @example
101
+ #
102
+ # a = ['a', 'b', 'c']
103
+ # a.each { |x| puts x }
104
+ # # => 'a'
105
+ # # => 'b'
106
+ # # => 'c'
107
+ #
108
+ # TODO: needs to return enumerator for no block.
109
+ #
110
+ # @return [Array] returns the receiver
111
+ def each
112
+ `for (var i = 0, length = self.length; i < length; i++) {
113
+ try {
114
+ #{yield `self[i]`};
115
+ } catch (e) {
116
+ switch (e.$keyword) {
117
+ case 2:
118
+ return e.$value;
119
+ default:
120
+ throw e;
121
+ }
122
+ }
123
+ }
124
+
125
+ return self;`
126
+ end
127
+
128
+ # Similar to {#each}, but also passes in the current element index to the
129
+ # block.
130
+ def each_with_index
131
+ `for (var i = 0, length = self.length; i < length; i++) {
132
+ try {
133
+ #{yield `self[i]`, `i`};
134
+ } catch (e) {
135
+ switch (e.$keyword) {
136
+ case 2:
137
+ return e.$value;
138
+ default:
139
+ throw e;
140
+ }
141
+ }
142
+ }
143
+
144
+ return self;`
145
+ end
146
+
147
+ # Same as {#each}, but passes the index of the element instead of the
148
+ # element itself.
149
+ #
150
+ # If no block given, an enumerator is returned instead.
151
+ #
152
+ # TODO: enumerator functionality not yet implemented.
153
+ #
154
+ # @example
155
+ #
156
+ # a = [1, 2, 3]
157
+ # a.each_index { |x| puts x }
158
+ # # => 0
159
+ # # => 1
160
+ # # => 2
161
+ #
162
+ # @return [Array] returns receiver
163
+ def each_index
164
+ `for (var i = 0, length = self.length; i < length; i++) {
165
+ try {
166
+ #{yield `i`};
167
+ } catch (e) {
168
+ switch (e.$keyword) {
169
+ case 2:
170
+ return e.$value;
171
+ default:
172
+ throw e;
173
+ }
174
+ }
175
+ }
176
+
177
+ return self;`
178
+ end
179
+
180
+ # Append - pushes the given object(s) onto the end of this array. This
181
+ # expression returns the array itself, so several appends may be chained
182
+ # together.
183
+ #
184
+ # @example
185
+ #
186
+ # a = ['a', 'b', 'c']
187
+ # a.push 'd', 'e', 'f'
188
+ # # => ['a', 'b', 'c', 'd', 'e', 'f'
189
+ #
190
+ # @param [Object] obj the object(s) to push onto the array
191
+ # @return [Array] returns the receiver
192
+ def push(*objs)
193
+ `for (var i = 0, length = objs.length; i < length; i++) {
194
+ self.push(objs[i]);
195
+ }
196
+
197
+ return self;`
198
+ end
199
+
200
+ # Returns the index of the first object in `self` such that it is `==` to
201
+ # `obj`. If a block is given instead of an argument, returns first object for
202
+ # which the block is true. Returns `nil` if no match is found. See also
203
+ # {#rindex}.
204
+ #
205
+ # @example
206
+ #
207
+ # a = ['a', 'b', 'c']
208
+ # a.index('a') # => 0
209
+ # a.index('z') # => nil
210
+ # a.index { |x| x == 'b' } # => 1
211
+ #
212
+ # @param [Object] obj the object to look for
213
+ # @return [Numeric, nil] result
214
+ def index(obj)
215
+ `for (var i = 0, length = self.length; i < length; i++) {
216
+ if (#{`self[i]` == obj}.$r) {
217
+ return i;
218
+ }
219
+ }
220
+
221
+ return nil;`
222
+ end
223
+
224
+ # Concatenation - returns a new array built by concatenating the two arrays
225
+ # together to produce a third array.
226
+ #
227
+ # @example
228
+ #
229
+ # [1, 2, 3] + [4, 5]
230
+ # # => [1, 2, 3, 4, 5]
231
+ #
232
+ # @param [Array] other the array to concat with
233
+ # @return [Array] returns new concatenated array
234
+ def +(other)
235
+ `return self.concat(other);`
236
+ end
237
+
238
+ # Difference. Creates a new array that is a copy of the original array,
239
+ # removing any items that also appear in `other`.
240
+ #
241
+ # @example
242
+ #
243
+ # [1, 2, 3, 3, 4, 4, 5] - [1, 2, 4]
244
+ # # => [3, 3, 5]
245
+ #
246
+ # @param [Array] other array to use for difference
247
+ # @return [Array] new array
248
+ def -(other)
249
+ raise "Array#- not yet implemented"
250
+ end
251
+
252
+ # Equality. Two arrays are equal if they contain the same number of elements
253
+ # and if each element is equal to (according to {Object#==} the corresponding
254
+ # element in the second array.
255
+ #
256
+ # @example
257
+ #
258
+ # ['a', 'c'] == ['a', 'c', 7] # => false
259
+ # ['a', 'c', '7'] == ['a', 'c', 7] # => true
260
+ # ['a', 'c', 7] == ['a', 'd', 'f'] # => false
261
+ #
262
+ # @param [Array] other array to compare self with
263
+ # @return [Boolean] if the arrays are equal
264
+ def ==(other)
265
+ `if (self.$hash() == other.$hash()) return Qtrue;
266
+ if (self.length != other.length) return Qfalse;
267
+
268
+ for (var i = 0; i < self.length; i++) {
269
+ if (!#{`self[i]` == `other[i]`}.$r) {
270
+ return Qfalse;
271
+ }
272
+ }
273
+
274
+ return Qtrue;`
275
+ end
276
+
277
+ # Searches through an array whose elements are also arrays, comparing `obj`
278
+ # with their first element of each contained array using {Object#==}. Returns
279
+ # the first contained array that matches (that is, the first associated array)
280
+ # or `nil` if no match is found. See also {#rassoc}.
281
+ #
282
+ # @example
283
+ #
284
+ # s1 = ['colors', 'red', 'blue', 'green']
285
+ # s2 = ['letters', 'a', 'b', 'c']
286
+ # s3 = 'foo'
287
+ # a = [s1, s2, s3]
288
+ #
289
+ # a.assoc 'letters' # => ['letters', 'a', 'b', 'c']
290
+ # a.assoc 'foo' # => nil
291
+ def assoc(obj)
292
+ `var arg;
293
+
294
+ for (var i = 0; i < self.length; i++) {
295
+ arg = self[i];
296
+
297
+ if (arg.length && #{`arg[0]` == obj}.$r) {
298
+ return arg;
299
+ }
300
+ }
301
+
302
+ return nil;`
303
+ end
304
+
305
+ # Returns the element at `index`. A negative index counts from the end of the
306
+ # receiver. Returns `nil` if the given index is out of range. See also {#[]}.
307
+ #
308
+ # @example
309
+ #
310
+ # a = ['a', 'b', 'c', 'd', 'e']
311
+ # a.at 0 # => 'a'
312
+ # a.at -1 # => 'e'
313
+ # a.at 324 # => nil
314
+ #
315
+ # @param [Numeric] index the index to get
316
+ # @return [Object, nil] returns nil or the result
317
+ def at(idx)
318
+ `if (idx < 0) idx += self.length;
319
+
320
+ if (idx < 0 || idx >= self.length) return nil;
321
+ return self[idx];`
322
+ end
323
+
324
+ # Removes all elements from the receiver.
325
+ #
326
+ # @example
327
+ #
328
+ # a = ['a', 'b', 'c', 'd', 'e']
329
+ # a.clear # => []
330
+ #
331
+ # @return [Array] returns the receiver
332
+ def clear
333
+ `self.splice(0);
334
+ return self;`
335
+ end
336
+
337
+ # Yields the block, passing in successive elements from the receiver,
338
+ # returning an array containing those elements for which the block returns a
339
+ # true value.
340
+ #
341
+ # @example
342
+ #
343
+ # a = [1, 2, 3, 4, 5, 6]
344
+ # a.select { |x| x > 4 }
345
+ # # => [5, 6]
346
+ #
347
+ # @return [Array] returns a new array of selected elements
348
+ def select
349
+ `var result = [], arg;
350
+
351
+ for (var i = 0; i < self.length; i++) {
352
+ try {
353
+ arg = self[i];
354
+ if (#{yield `arg`}.$r) {
355
+ result.push(arg);
356
+ }
357
+ } catch (e) {
358
+ switch (e.$keyword) {
359
+ case 2:
360
+ return e.$value;
361
+ default:
362
+ throw e;
363
+ }
364
+ }
365
+ }
366
+
367
+ return result;`
368
+ end
369
+
370
+ # Yields the block once for each element of the receiver. Creates a new array
371
+ # containing the values returned by the block. See also {Enumerable#collect}.
372
+ #
373
+ # @example
374
+ #
375
+ # a = ['a', 'b', 'c', 'd']
376
+ # a.collect { |x| x + '!' } # => ['a!', 'b!', 'c!', 'd!']
377
+ # a # => ['a', 'b', 'c', 'd']
378
+ #
379
+ # @return [Array] new array
380
+ def collect
381
+ `var result = [];
382
+
383
+ for (var i = 0; i < self.length; i++) {
384
+ try {
385
+ result.push(#{yield `self[i]`});
386
+ } catch (e) {
387
+ switch (e.$keyword) {
388
+ case 2:
389
+ return e.$value;
390
+ default:
391
+ throw e;
392
+ }
393
+ }
394
+ }
395
+
396
+ return result;`
397
+ end
398
+
399
+ # alias_method 'map', 'collect'
400
+
401
+ # Yields the block once for each element of `self`, replacing the element with
402
+ # the value returned by the block. See also {Enumerable#collect}.
403
+ #
404
+ # @example
405
+ #
406
+ # a = ['a', 'b', 'c', 'd']
407
+ # a.collect { |x| x + '!' }
408
+ # # => ['a!', 'b!', 'c!', 'd!']
409
+ # a
410
+ # # => ['a!', 'b!', 'c!', 'd!']
411
+ #
412
+ # @return [Array] returns the receiver
413
+ def collect!
414
+ `for (var i = 0; i < self.length; i++) {
415
+ try {
416
+ self[i] = #{yield `self[i]`};
417
+ } catch (e) {
418
+ switch (e.$keyword) {
419
+ case 2:
420
+ return e.$value;
421
+ default:
422
+ throw e;
423
+ }
424
+ }
425
+ }
426
+
427
+ return self;`
428
+ end
429
+
430
+ # Duplicate.
431
+ def dup
432
+ `return self.slice(0);`
433
+ end
434
+
435
+ # Returns a copy of the receiver with all nil elements removed
436
+ #
437
+ # @example
438
+ #
439
+ # ['a', nil, 'b', nil, 'c', nil].compact
440
+ # # => ['a', 'b', 'c']
441
+ #
442
+ # @return [Array] new Array
443
+ def compact
444
+ `var result = [], length = self.length;
445
+
446
+ for (var i = 0; i < length; i++) {
447
+ if (self[i] != nil) {
448
+ result.push(self[i]);
449
+ }
450
+ }
451
+
452
+ return result;`
453
+ end
454
+
455
+ # Removes nil elements from the receiver. Returns nil if no changes were made,
456
+ # otherwise returns self.
457
+ #
458
+ # @example
459
+ #
460
+ # ['a', nil, 'b', nil, 'c'].compact!
461
+ # # => ['a', 'b', 'c']
462
+ #
463
+ # ['a', 'b', 'c'].compact!
464
+ # # => nil
465
+ #
466
+ # @return [Array, nil] returns either the receiver or nil
467
+ def compact!
468
+ `var length = self.length;
469
+
470
+ for (var i = 0; i < length; i++) {
471
+ if (self[i] == nil) {
472
+ self.splice(i, 1);
473
+ i--;
474
+ }
475
+ }
476
+
477
+ return length == self.length ? nil : self;`
478
+ end
479
+
480
+ # Appends the elements of `other` to `self`.
481
+ #
482
+ # @example
483
+ #
484
+ # ['a', 'b'].concat ['c', 'd']
485
+ # # => ['a', 'b', 'c', 'd']
486
+ #
487
+ # @param [Array] other array to concat
488
+ # @return [Array] returns the receiver
489
+ def concat(other)
490
+ `var length = other.length;
491
+
492
+ for (var i = 0; i < length; i++) {
493
+ self.push(other[i]);
494
+ }
495
+
496
+ return self;`
497
+ end
498
+
499
+ # Returns the number of elements. If an argument is given, counts the number
500
+ # of elements which equals to `obj`. If a block is given, counts the number of
501
+ # elements yielding a true value.
502
+ #
503
+ # @example
504
+ #
505
+ # ary = [1, 2, 4, 2]
506
+ # ary.count # => 4
507
+ # ary.count(2) # =>2
508
+ #
509
+ # @param [Object] obj object to check
510
+ # @return [Numeric] count or count of obj
511
+ def count(obj)
512
+ `if (obj != undefined) {
513
+ var total = 0;
514
+
515
+ for (var i = 0; i < self.length; i++) {
516
+ if (#{`self[i]` == obj}.$r) {
517
+ total++;
518
+ }
519
+ }
520
+
521
+ return total;
522
+ } else {
523
+ return self.length;
524
+ }`
525
+ end
526
+
527
+ # Deletes items from `self` that are equal to `obj`. If any items are found,
528
+ # returns `obj`. If the item is not found, returns `nil`. If the optional code
529
+ # block is given, returns the result of block if the item is not found.
530
+ #
531
+ # @example
532
+ #
533
+ # a = ['a', 'b', 'b', 'b', 'c']
534
+ #
535
+ # a.delete 'b'
536
+ # # => 'b'
537
+ # a
538
+ # # => ['a', 'c']
539
+ #
540
+ # a.delete 'z'
541
+ # # => nil
542
+ #
543
+ # @param [Object] obj object to delete
544
+ # @return [Object, nil] returns obj or nil
545
+ def delete(obj)
546
+ `var length = self.length;
547
+
548
+ for (var i = 0; i < self.length; i++) {
549
+ if (#{`self[i]` == obj}.$r) {
550
+ self.splice(i, 1);
551
+ i--;
552
+ }
553
+ }
554
+
555
+ return length == self.length ? nil : obj;`
556
+ end
557
+
558
+ # Deletes the element at the specified index, returning that element, or nil
559
+ # if the index is out of range.
560
+ #
561
+ # @example
562
+ #
563
+ # a = ['ant', 'bat', 'cat', 'dog']
564
+ # a.delete_at 2
565
+ # # => 'cat'
566
+ # a
567
+ # # => ['ant', 'bat', 'dog']
568
+ # a.delete_at 99
569
+ # # => nil
570
+ #
571
+ # @param [Numeric] idx the index to delete
572
+ # @return [Object, nil] returns the deleted object or nil
573
+ def delete_at(idx)
574
+ `if (idx < 0) idx += self.length;
575
+ if (idx < 0 || idx >= self.length) return nil;
576
+ var res = self[idx];
577
+ self.splice(idx, 1);
578
+ return self;`
579
+ end
580
+
581
+ # Deletes every element of `self` for which `block` evaluates to true.
582
+ #
583
+ # @example
584
+ #
585
+ # a = [1, 2, 3]
586
+ # a.delete_if { |x| x >= 2 }
587
+ # # => [1]
588
+ #
589
+ # @return [Array] returns amended receiver
590
+ def delete_if
591
+ `for (var i = 0; i < self.length; i++) {
592
+ try {
593
+ if (#{yield `self[i]`}.$r) {
594
+ self.splice(i, 1);
595
+ i--;
596
+ }
597
+ } catch (e) {
598
+ switch(e.$keyword) {
599
+ case 2:
600
+ return e.$value;
601
+ default:
602
+ throw e;
603
+ }
604
+ }
605
+ }
606
+
607
+ return self;`
608
+ end
609
+
610
+ # Drop first `n` elements from receiver, and returns remaining elements in
611
+ # array.
612
+ #
613
+ # @example
614
+ #
615
+ # a = [1, 2, 3, 4, 5, 6]
616
+ # a.drop 3
617
+ # # => [4, 5, 6]
618
+ #
619
+ # @param [Number] n number of elements to drop
620
+ # @return [Array] returns new array
621
+ def drop(n)
622
+ `if (n > self.length) return [];
623
+ return self.slice(n);`
624
+ end
625
+
626
+ # Drop elements up to, but not including, the first element for which the
627
+ # block returns nil or false, and returns an array containing the remaining
628
+ # elements.
629
+ #
630
+ # @example
631
+ #
632
+ # a = [1, 2, 3, 4, 5, 6]
633
+ # a.drop_while { |i| i < 3 }
634
+ # # => [3, 4, 5, 6]
635
+ #
636
+ # @return [Array] returns a new array
637
+ def drop_while
638
+ `for (var i = 0; i < self.length; i++) {
639
+ if (!#{yield `self[i]`}.$r) {
640
+ return self.slice(i);
641
+ }
642
+ }
643
+
644
+ return [];`
645
+ end
646
+
647
+ # Returns `true` if the receiver contains no elements, `false` otherwise.
648
+ #
649
+ # @example
650
+ #
651
+ # [].empty?
652
+ # # => true
653
+ #
654
+ # @return [false, true] empty or not
655
+ def empty?
656
+ `return self.length == 0 ? Qtrue : Qfalse;`
657
+ end
658
+
659
+ # Tries to return the element as position `index`. If the index lies outside
660
+ # the array, the first form throws an IndexError exception, the second form
661
+ # returns `default`, and the third form returns the value of invoking the
662
+ # block, passing in the index. Negative values of `index` count from the end
663
+ # of the array.
664
+ #
665
+ # @example First form
666
+ #
667
+ # a = [11, 22, 33, 44]
668
+ # a.fetch 1
669
+ # # => 22
670
+ # a.fetch -1
671
+ # # => 44
672
+ #
673
+ # @example Second form
674
+ #
675
+ # a.fetch 4, 'cat'
676
+ # # => 'cat'
677
+ #
678
+ # @example Third form
679
+ #
680
+ # a.fetch 4 { |i| i * i }
681
+ # # => 16
682
+ #
683
+ # @param [Numeric] idx
684
+ # @param [Object] defaults
685
+ # @return [Object] returns result
686
+ def fetch(idx, defaults)
687
+ `var original = idx;
688
+
689
+ if (idx < 0) idx += self.length;
690
+ if (idx < 0 || idx >= self.length) {
691
+ if (defaults == undefined)
692
+ return rb_raise("Index Error: Array#fetch");
693
+ else if (__block__)
694
+ return #{yield `original`};
695
+ else
696
+ return defaults;
697
+ }
698
+
699
+ return self[idx];`
700
+ end
701
+
702
+ # Returns the first element, or the first `n` elements, of the array. If the
703
+ # array is empty, the first form returns `nil`, and the second form returns an
704
+ # empty array.
705
+ #
706
+ # @example
707
+ #
708
+ # a = ['q', 'r', 's', 't']
709
+ # a.first
710
+ # # => q
711
+ # a.first 2
712
+ # # => ['q', 'r']
713
+ #
714
+ # @param [Numeric] count number of elements
715
+ # @return [Object, Array] object or array of objects
716
+ def first(count = nil)
717
+ `if (count == nil) {
718
+ if (self.length == 0) return nil;
719
+ return self[0];
720
+ }
721
+ return self.slice(0, count);`
722
+ end
723
+
724
+ # Returns a new array that is a one-dimensional flattening of this array
725
+ # (recursively). That is, for evey element that is an array, extract its
726
+ # elements into the new array. If the optional `level` argument determines the
727
+ # level of recursion to flatten.
728
+ #
729
+ # @example
730
+ #
731
+ # s = [1, 2, 3]
732
+ # # => [a, 2, 3]
733
+ # t = [4, 5, 6, [7, 8]]
734
+ # # => [4, 5, 6, [7, 8]]
735
+ # a = [s, t, 9, 10]
736
+ # # => [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
737
+ # a.flatten
738
+ # # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
739
+ # a = [1, 2, [3, [4, 5]]]
740
+ # a.flatten 1
741
+ # # => [1, 2, 3, [4, 5]]
742
+ #
743
+ # @param [Numeric] level the level to flatten
744
+ # @return [Array] returns new array
745
+ def flatten(level = nil)
746
+ `var result = [], item;
747
+
748
+ for (var i = 0; i < self.length; i++) {
749
+ item = self[i];
750
+
751
+ if (item.hasOwnProperty('length')) {
752
+ if (level == nil)
753
+ result = result.concat(#{`item`.flatten});
754
+ else if (level == 0)
755
+ result.push(item);
756
+ else
757
+ result = result.concat(#{`item`.flatten `level - 1`});
758
+ } else {
759
+ result.push(item);
760
+ }
761
+ }
762
+
763
+ return result;`
764
+ end
765
+
766
+ # Flattens the receiver in place. Returns `nil` if no modifications were made.
767
+ # If the optional level argument determines the level of recursion to flatten.
768
+ #
769
+ # @example
770
+ #
771
+ # a = [1, 2, [3, [4, 5]]]
772
+ # a.flatten!
773
+ # # => [1, 2, 3, 4, 5]
774
+ # a.flatten!
775
+ # # => nil
776
+ # a
777
+ # # => [1, 2, 3, 4, 5]
778
+ #
779
+ # @param [Number] level to flatten to
780
+ # @return [Array] returns the receiver
781
+ def flatten!(level = nil)
782
+ `var length = self.length;
783
+ var result = #{self.flatten level};
784
+ self.splice(0);
785
+
786
+ for (var i = 0; i < result.length; i++) {
787
+ self.push(result[i]);
788
+ }
789
+
790
+ if (self.length == length)
791
+ return nil;
792
+
793
+ return self;`
794
+ end
795
+
796
+ # Returns true if the given object is present in `self`, false otherwise.
797
+ #
798
+ # @example
799
+ #
800
+ # a = ['a', 'b', 'c']
801
+ # a.include? 'b'
802
+ # # => true
803
+ # a.include? 'z'
804
+ # # => false
805
+ def include?(member)
806
+ `for (var i = 0; i < self.length; i++) {
807
+ if (#{`self[i]` == member}.$r) {
808
+ return #{true};
809
+ }
810
+ }
811
+
812
+ return #{false};`
813
+ end
814
+
815
+ # Replaces the contents of `self` with the contents of `other`, truncating or
816
+ # expanding if necessary.
817
+ #
818
+ # @example
819
+ #
820
+ # a = ['a', 'b', 'c', 'd', 'e']
821
+ # a.replace ['x', 'y', 'z']
822
+ # # => ['x', 'y', 'z']
823
+ # a
824
+ # # => ['x', 'y', 'z']
825
+ #
826
+ # @param [Array] other array to replace contents with
827
+ # @return [Array] returns the receiver
828
+ def replace(other)
829
+ `self.splice(0);
830
+
831
+ for (var i = 0; i < other.length; i++) {
832
+ self.push(other[i]);
833
+ }
834
+
835
+ return self;`
836
+ end
837
+
838
+ # Inserts the given values before the element with the given index (which may
839
+ # be negative).
840
+ #
841
+ # @example
842
+ #
843
+ # a = ['a', 'b', 'c', 'd']
844
+ # a.insert 2, 99
845
+ # # => ['a', 'b', 99, 'c', 'd']
846
+ # a.insert -2, 1, 2, 3
847
+ # # => ['a', 'b', 99, 'c', 1, 2, 3, 'd']
848
+ #
849
+ # @param [Numeric] idx the index for insertion
850
+ # @param [Object] objs objects to insert
851
+ # @return [Array] returns the receiver
852
+ def insert(idx, *objs)
853
+ `if (idx < 0) idx += self.length;
854
+
855
+ if (idx < 0 || idx >= self.length)
856
+ rb_raise("IndexError: out of range");
857
+
858
+ self.splice.apply(self, [idx, 0].concat(objs));
859
+ return self;`
860
+ end
861
+
862
+ # Returns a string created by converting each element of the array to a string
863
+ # seperated by `sep`.
864
+ #
865
+ # @example
866
+ #
867
+ # ['a', 'b', 'c'].join
868
+ # # => 'abc'
869
+ # ['a', 'b', 'c'].join '-'
870
+ # # => 'a-b-c'
871
+ #
872
+ # @param [String] sep the separator
873
+ # @return [String] joined string
874
+ def join(sep = '')
875
+ `var result = [];
876
+
877
+ for (var i = 0; i < self.length; i++) {
878
+ result.push(#{`self[i]`.to_s});
879
+ }
880
+
881
+ return result.join(sep);`
882
+ end
883
+
884
+ # Deletes every element of `self` for which the block evaluates to false.
885
+ #
886
+ # @example
887
+ #
888
+ # a = [1, 2, 3, 4, 5, 6]
889
+ # a.keep_if { |x| x < 4 }
890
+ # # => [1, 2, 3]
891
+ #
892
+ # @return [Array] returns the receiver
893
+ def keep_if
894
+ `for (var i = 0; i < self.length; i++) {
895
+ if (!#{yield `self[i]`}.$r) {
896
+ self.splice(i, 1);
897
+ i--;
898
+ }
899
+ }
900
+
901
+ return self;`
902
+ end
903
+
904
+ # Return the last element(s) of `self`. If the array is empty, the first form
905
+ # returns `nil`.
906
+ #
907
+ # @example
908
+ #
909
+ # a = ['w', 'x', 'y', 'z']
910
+ # a.last
911
+ # # => 'z'
912
+ # a.last 2
913
+ # # => ['y', 'z']
914
+ #
915
+ # @param [Number] count the number of items to get
916
+ # @return [Object, Array] result
917
+ def last(count = nil)
918
+ `if (count == nil) {
919
+ if (self.length == 0) return nil;
920
+ return self[self.length - 1];
921
+ } else {
922
+ if (count > self.length) count = self.length;
923
+ return self.slice(self.length - count, self.length);
924
+ }`
925
+ end
926
+
927
+ # Removes the last element from `self` and returns it, or `nil` if the array
928
+ # is empty. If a count is given, returns an array of the last `count`
929
+ # elements (or less).
930
+ #
931
+ # @example
932
+ #
933
+ # a = ['a', 'b', 'c', 'd']
934
+ # a.pop
935
+ # # => 'd'
936
+ # a.pop 2
937
+ # # => 'b', 'c'
938
+ # a
939
+ # # => ['a']
940
+ #
941
+ # @param [Numeric] count number to pop
942
+ # @return [Array] returns popped items
943
+ def pop(count = nil)
944
+ `if (count == nil) {
945
+ if (self.length) return self.pop();
946
+ return nil;
947
+ } else {
948
+ return self.splice(self.length - count, self.length);
949
+ }`
950
+ end
951
+
952
+ # Searches through the array whose elements are also arrays. Compares `obj`
953
+ # with the second element of each contained array using `==`. Returns the
954
+ # first contained array that matches.
955
+ #
956
+ # @example
957
+ #
958
+ # a = [[1, 'one'], [2, 'two'], [3, 'three'], ['ii', 'two']]
959
+ # a.rassoc 'two'
960
+ # # => [2, 'two']
961
+ # a.rassoc 'four'
962
+ # # => nil
963
+ #
964
+ # @param [Object] obj object to search for
965
+ # @return [Object, nil] result or nil
966
+ def rassoc(obj)
967
+ `var test;
968
+
969
+ for (var i = 0; i < self.length; i++) {
970
+ test = self[i];
971
+ if (test.hasOwnProperty('length') && test[1] != undefined) {
972
+ console.log("trying " + i);
973
+ if (#{`test[1]` == obj}.$r) return test;
974
+ }
975
+ }
976
+
977
+ return nil;`
978
+ end
979
+
980
+ # Returns a new array containing the items in `self` for which the block is
981
+ # not true. See also {#delete_if}.
982
+ #
983
+ # @example
984
+ #
985
+ # a = [1, 2, 3, 4, 5, 6]
986
+ # a.reject { |x| x > 3 }
987
+ # # => [1, 2, 3]
988
+ # a
989
+ # # => [1, 2, 3, 4, 5, 6]
990
+ #
991
+ # @return [Array] returns the receiver
992
+ def reject
993
+ `var result = [];
994
+
995
+ for (var i = 0; i < self.length; i++) {
996
+ if (!#{yield `self[i]`}.$r) {
997
+ result.push(self[i]);
998
+ }
999
+ }
1000
+
1001
+ return result;`
1002
+ end
1003
+
1004
+ # Equivalent to {#delete_if!}, deleting elements from self for which the block
1005
+ # evaluates to true, but returns nil if no changes were made.
1006
+ #
1007
+ # @example
1008
+ #
1009
+ # a = [1, 2, 3, 4, 5, 6]
1010
+ # a.reject! { |x| x > 3 }
1011
+ # # => [1, 2, 3]
1012
+ # a.reject! { |x| x > 3 }
1013
+ # # => nil
1014
+ # a
1015
+ # # => [1, 2, 3]
1016
+ #
1017
+ # @return [Array] returns receiver
1018
+ def reject!
1019
+ `var length = self.length;
1020
+
1021
+ for (var i = 0; i < self.length; i++) {
1022
+ if (#{yield `self[i]`}.$r) {
1023
+ self.splice(i, 1);
1024
+ i--;
1025
+ }
1026
+ }
1027
+
1028
+ return self.length == length ? nil : self;`
1029
+ end
1030
+
1031
+ # Returns a new array containing the receiver's elements in reverse order.
1032
+ #
1033
+ # @example
1034
+ #
1035
+ # ['a', 'b', 'c'].reverse
1036
+ # # => ['c', 'b', 'a']
1037
+ # [1].reverse
1038
+ # # => [1]
1039
+ #
1040
+ # @return [Array] return new array
1041
+ def reverse
1042
+ `var result = [];
1043
+
1044
+ for (var i = self.length - 1; i >= 0; i--) {
1045
+ result.push(self[i]);
1046
+ }
1047
+
1048
+ return result;`
1049
+ end
1050
+
1051
+ # Reverses the receiver in place.
1052
+ #
1053
+ # @example
1054
+ #
1055
+ # a = ['a', 'b', 'c']
1056
+ # a.reverse!
1057
+ # # => ['c', 'b', 'a']
1058
+ # a
1059
+ # # => ['c', 'b', 'a']
1060
+ #
1061
+ # @return [Array] returns the receiver
1062
+ def reverse!
1063
+ `var length = self.length / 2, tmp;
1064
+
1065
+ for (var i = 0; i < length; i++) {
1066
+ tmp = self[i];
1067
+ self[i] = self[self.length - (i + 1)];
1068
+ self[self.length - (i + 1)] = tmp;
1069
+ }
1070
+
1071
+ return self;`
1072
+ end
1073
+
1074
+ # Same as {#each}, but traverses the receiver in reverse order
1075
+ #
1076
+ # @example
1077
+ #
1078
+ # a = ['a', 'b', 'c']
1079
+ # a.reverse_each { |x| puts x }
1080
+ # # => 'c'
1081
+ # # => 'b'
1082
+ # # => 'a'
1083
+ #
1084
+ # @return [Array] returns the receiver
1085
+ def reverse_each
1086
+ `for (var i = self.length - 1; i >= 0; i--) {
1087
+ try {
1088
+ #{yield `self[i]`};
1089
+ } catch (e) {
1090
+ switch (e.$keyword) {
1091
+ case 2:
1092
+ return e['@exit_value'];
1093
+ default:
1094
+ throw e;
1095
+ }
1096
+ }
1097
+ }
1098
+
1099
+ return self;`
1100
+ end
1101
+
1102
+ # Returns the index of the last object in self that is == to object. If a
1103
+ # block is given instead of an argument, returns the first object for which
1104
+ # block is true, starting from the last object. Returns `nil` if no match is
1105
+ # found.
1106
+ #
1107
+ # @example
1108
+ #
1109
+ # a = ['a', 'b', 'b', 'b', 'c']
1110
+ # a.rindex 'b'
1111
+ # # => 3
1112
+ # a.rindex 'z'
1113
+ # # => nil
1114
+ # a.rindex { |x| x == 'b' }
1115
+ # # => 3
1116
+ #
1117
+ # @return [Object, nil] returns result or nil
1118
+ def rindex(obj = `undefined`)
1119
+ `if (obj != undefined) {
1120
+ for (var i = self.length - 1; i >=0; i--) {
1121
+ if (#{`self[i]` == obj}.$r) {
1122
+ return i;
1123
+ }
1124
+ }
1125
+ } else if (true || __block__) {
1126
+ rb_raise("array#rindex needs to do block action");
1127
+ }
1128
+
1129
+ return nil;`
1130
+ end
1131
+
1132
+ # Invokes the block passing in successive elements from `self`, deleting the
1133
+ # elements for which the block returns a false value. It returns `self` if
1134
+ # changes were made, otherwise it returns `nil`.
1135
+ #
1136
+ # @example
1137
+ #
1138
+ # a = [1, 2, 3, 4, 5, 6]
1139
+ # a.select! { |x| x > 4 }
1140
+ # # => [5, 6]
1141
+ # a.select! { |x| x > 4 }
1142
+ # # => nil
1143
+ # a
1144
+ # # => [5, 6]
1145
+ #
1146
+ # @return [Array] returns receiver
1147
+ def select!
1148
+ `var length = self.length;
1149
+
1150
+ for (var i = 0; i < self.length; i++) {
1151
+ if (!#{yield `self[i]`}.$r) {
1152
+ self.splice(i, 1);
1153
+ i--;
1154
+ }
1155
+ }
1156
+
1157
+ return self.length == length ? nil : self;`
1158
+ end
1159
+
1160
+ # Returns the first element of `self` and removes it (shifting all other
1161
+ # elements down by one). Returns `nil` if the array is empty.
1162
+ #
1163
+ # If a number `n` is given, returns an array of the first n elements (or
1164
+ # less), just like {#slice} does.
1165
+ #
1166
+ # @example
1167
+ #
1168
+ # a = ['a', 'b', 'c']
1169
+ # a.shift
1170
+ # # => 'a'
1171
+ # a
1172
+ # # => ['b', 'c']
1173
+ # a = ['a', 'b', 'c']
1174
+ # a.shift 2
1175
+ # # => ['a', 'b']
1176
+ # a
1177
+ # # => ['c']
1178
+ #
1179
+ # @param [Numeric] count elements to shift
1180
+ # @return [Array] result
1181
+ def shift(count = nil)
1182
+ `if (count != nil)
1183
+ return self.splice(0, count);
1184
+
1185
+ if (self.length)
1186
+ return self.shift();
1187
+
1188
+ return nil;`
1189
+ end
1190
+
1191
+ # Deletes the element(s) given by an `index` (optionally with a length) or
1192
+ # by a range. Returns the deleted object(s), or `nil` if the index is out of
1193
+ # range.
1194
+ #
1195
+ # @example
1196
+ #
1197
+ # a = ['a', 'b', 'c']
1198
+ # a.slice! 1
1199
+ # # => 'b'
1200
+ # a
1201
+ # # => ['a', 'c']
1202
+ # a.slice! -1
1203
+ # # => 'c'
1204
+ # a
1205
+ # # => ['a']
1206
+ # a.slice! 100
1207
+ # # => nil
1208
+ #
1209
+ # TODO does not yet work with ranges
1210
+ #
1211
+ # @param [Range, Number] index to begin with
1212
+ # @param [Number] length last index
1213
+ # @return [Array, nil] result
1214
+ def slice!(index, length = nil)
1215
+ `var size = self.length;
1216
+
1217
+ if (index < 0) index += size;
1218
+
1219
+ if (index >= size || index < 0) return nil;
1220
+
1221
+ if (length != nil) {
1222
+ if (length <= 0 || length > self.length) return nil;
1223
+ return self.splice(index, index + length);
1224
+ } else {
1225
+ return self.splice(index, 1)[0];
1226
+ }`
1227
+ end
1228
+
1229
+ # Returns first `count` elements from ary.
1230
+ #
1231
+ # @example
1232
+ #
1233
+ # a = [1, 2, 3, 4, 5, 6]
1234
+ # a.take 3
1235
+ # # => [1, 2, 3]
1236
+ #
1237
+ # @return [Array] array of elements
1238
+ def take(count)
1239
+ `return self.slice(0, count);`
1240
+ end
1241
+
1242
+
1243
+ # Passes elements to the block until the block returns a false value, then
1244
+ # stops iterating and returns an array of all prior elements.
1245
+ #
1246
+ # @example
1247
+ #
1248
+ # a = [1, 2, 3, 4, 5, 6]
1249
+ # a.take_while { |i| i < 3 }
1250
+ # # => [1, 2]
1251
+ #
1252
+ # @return [Array] new array with elements
1253
+ def take_while
1254
+ `var result = [];
1255
+
1256
+ for (var i = 0; i < self.length; i++) {
1257
+ try {
1258
+ if (#{yield `self[i]`}.$r) {
1259
+ result.push(self[i]);
1260
+ } else {
1261
+ break;
1262
+ }
1263
+ } catch (e) {
1264
+ switch (e.$keyword) {
1265
+ case 2:
1266
+ return e['@exit_value'];
1267
+
1268
+ default:
1269
+ throw e;
1270
+ }
1271
+ }
1272
+ }
1273
+
1274
+ return result;`
1275
+ end
1276
+
1277
+ # Returns the receiver.
1278
+ #
1279
+ # @example
1280
+ #
1281
+ # a = [1, 2, 3]
1282
+ # a.to_a
1283
+ # # => [1, 2, 3]
1284
+ #
1285
+ # @return [Array] returns the receiver
1286
+ def to_a
1287
+ self
1288
+ end
1289
+
1290
+ # Returns a new array by removing duplicate values in `self`.
1291
+ #
1292
+ # @example
1293
+ #
1294
+ # a = ['a', 'a', 'b', 'b', 'c']
1295
+ # a.uniq
1296
+ # # => ['a', 'b', 'c']
1297
+ # a
1298
+ # # => ['a', 'a', 'b', 'b', 'c']
1299
+ #
1300
+ # @return [Array]
1301
+ def uniq
1302
+ `var result = [], seen = [];
1303
+
1304
+ for (var i = 0; i < self.length; i++) {
1305
+ var test = self[i], hash = test.$hash();
1306
+ if (seen.indexOf(hash) == -1) {
1307
+ seen.push(hash);
1308
+ result.push(test);
1309
+ }
1310
+ }
1311
+
1312
+ return result;`
1313
+ end
1314
+
1315
+ # Removes duplicate elements from `self`. Returns `nil` if no changes are
1316
+ # made (that is, no duplicates are found).
1317
+ #
1318
+ # @example
1319
+ #
1320
+ # a = ['a', 'a', 'b', 'b', 'c']
1321
+ # a.uniq!
1322
+ # # => ['a', 'b', 'c']
1323
+ # a.uniq!
1324
+ # # => nil
1325
+ #
1326
+ # @return [Array] returns receiver
1327
+ def uniq!
1328
+ `var seen = [], length = self.length;
1329
+
1330
+ for (var i = 0; i < self.length; i++) {
1331
+ var test = self[i], hash = test.$hash();
1332
+ if (seen.indexOf(hash) == -1) {
1333
+ seen.push(hash);
1334
+ } else {
1335
+ self.splice(i, 1);
1336
+ i--;
1337
+ }
1338
+ }
1339
+
1340
+ return self.length == length ? nil : self;`
1341
+ end
1342
+
1343
+ # Prepends objects to the front of `self`, moving other elements upwards.
1344
+ #
1345
+ # @example
1346
+ #
1347
+ # a = ['b', 'c', 'd']
1348
+ # a.unshift 'a'
1349
+ # # => ['a', 'b', 'c', 'd']
1350
+ # a.unshift 1, 2
1351
+ # # => [1, 2, 'a', 'b', 'c', 'd']
1352
+ #
1353
+ # @param [Object] objs objects to add
1354
+ # @return [Array] returns the receiver
1355
+ def unshift(*objs)
1356
+ `for (var i = objs.length - 1; i >= 0; i--) {
1357
+ self.unshift(objs[i]);
1358
+ }
1359
+
1360
+ return self;`
1361
+ end
1362
+
1363
+ # Set intersection - Returns a new array containing elements common to the
1364
+ # two arrays, with no duplicates.
1365
+ #
1366
+ # @example
1367
+ #
1368
+ # [1, 1, 3, 5] & [1, 2, 3]
1369
+ # # => [1, 3]
1370
+ #
1371
+ # @param [Array] other second array to intersect
1372
+ # @return [Array] new intersected array
1373
+ def &(other)
1374
+ `var result = [], seen = [];
1375
+
1376
+ for (var i = 0; i < self.length; i++) {
1377
+ var test = self[i], hash = test.$hash();
1378
+
1379
+ if (seen.indexOf(hash) == -1) {
1380
+ for (var j = 0; j < other.length; j++) {
1381
+ var test_b = other[j], hash_b = test_b.$hash();
1382
+
1383
+ if ((hash == hash_b) && seen.indexOf(hash) == -1) {
1384
+ seen.push(hash);
1385
+ result.push(test);
1386
+ }
1387
+ }
1388
+ }
1389
+ }
1390
+
1391
+ return result;`
1392
+ end
1393
+
1394
+ # Repitition - When given a string argument, acts the same as {#join}.
1395
+ # Otherwise, returns a new array build by concatenating the `num` copies of
1396
+ # self.
1397
+ #
1398
+ # @example With Number
1399
+ #
1400
+ # [1, 2, 3] * 3
1401
+ # # => [1, 2, 3, 1, 2, 3, 1, 2, 3]
1402
+ #
1403
+ # @example With String
1404
+ #
1405
+ # [1, 2, 3] * ','
1406
+ # # => '1,2,3'
1407
+ #
1408
+ # @param [String, Number] num string or number used to join or concat
1409
+ # @return [String, Array] depending on argument
1410
+ def *(arg)
1411
+ `if (typeof arg == 'string') {
1412
+ return #{self.join `arg`};
1413
+ } else {
1414
+ var result = [];
1415
+ for (var i = 0; i < parseInt(arg); i++) {
1416
+ result = result.concat(self);
1417
+ }
1418
+
1419
+ return result;
1420
+ }`
1421
+ end
1422
+
1423
+ # Element Reference - Returns the element at `index`, or returns a subarray
1424
+ # at index and counting for length elements, or returns a subarray if index
1425
+ # is a range. Negative indecies count backward from the end of the array (-1
1426
+ # is the last element). Returns `nil` if the index (or starting index) are
1427
+ # out of range.
1428
+ #
1429
+ # @example
1430
+ #
1431
+ # a = ['a', 'b', 'c', 'd', 'e']
1432
+ # a[2] + a[0] + a[1] # => 'cab'
1433
+ # a[6] # => nil
1434
+ # a[1, 2] # => ['b', 'c']
1435
+ # a[1..3] # => ['b', 'c', 'd']
1436
+ # a[4..7] # => ['e']
1437
+ # a[6..10] # => nil
1438
+ # a[-3, 3] # => ['c', 'd', 'e']
1439
+ # a[5] # => nil
1440
+ # a[5, 1] # => []
1441
+ # a[5..10] # => []
1442
+ #
1443
+ # @TODO: does not yet work with ranges
1444
+ #
1445
+ # @param [Range, Numeric] index to begin
1446
+ # @param [Numeric] length last index
1447
+ # @return [Array, Object, nil] result
1448
+ def [](index, length = `undefined`)
1449
+ `var size = self.length;
1450
+
1451
+ if (index < 0) index += size;
1452
+
1453
+ if (index >= size || index < 0) return nil;
1454
+
1455
+ if (length != undefined) {
1456
+ if (length <= 0) return [];
1457
+ return self.slice(index, index + length);
1458
+ } else {
1459
+ return self[index];
1460
+ }`
1461
+ end
1462
+
1463
+ # Element reference setting.
1464
+ #
1465
+ # @TODO: need to expand functionlaity.
1466
+ def []=(index, value)
1467
+ `return self[index] = value;`
1468
+ end
1469
+ end
1470
+