opal 0.0.1 → 0.1.0

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