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