opal-cj 0.7.0.beta1

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 (470) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.gitmodules +27 -0
  4. data/.rspec +3 -0
  5. data/.spectator +2 -0
  6. data/.spectator-mspec +3 -0
  7. data/.travis.yml +45 -0
  8. data/CHANGELOG.md +406 -0
  9. data/CONTRIBUTING.md +41 -0
  10. data/Gemfile +27 -0
  11. data/Guardfile +77 -0
  12. data/LICENSE +19 -0
  13. data/README.md +178 -0
  14. data/Rakefile +116 -0
  15. data/benchmarks/operators.rb +11 -0
  16. data/bin/opal +22 -0
  17. data/bin/opal-build +77 -0
  18. data/bin/opal-mspec +10 -0
  19. data/bin/opal-repl +72 -0
  20. data/config.ru +14 -0
  21. data/examples/rack/Gemfile +3 -0
  22. data/examples/rack/app/application.rb +13 -0
  23. data/examples/rack/app/user.rb +21 -0
  24. data/examples/rack/config.ru +7 -0
  25. data/examples/rack/index.html.erb +10 -0
  26. data/examples/sinatra/Gemfile +4 -0
  27. data/examples/sinatra/app/application.rb +7 -0
  28. data/examples/sinatra/config.ru +28 -0
  29. data/lib/mspec/opal/main.rb.erb +9 -0
  30. data/lib/mspec/opal/rake_task.rb +278 -0
  31. data/lib/mspec/opal/runner.rb +206 -0
  32. data/lib/mspec/opal/sprockets.js +57 -0
  33. data/lib/opal.rb +11 -0
  34. data/lib/opal/builder.rb +135 -0
  35. data/lib/opal/builder_processors.rb +165 -0
  36. data/lib/opal/cli.rb +145 -0
  37. data/lib/opal/cli_options.rb +149 -0
  38. data/lib/opal/cli_runners.rb +10 -0
  39. data/lib/opal/cli_runners/nodejs.rb +56 -0
  40. data/lib/opal/cli_runners/phantom.js +35 -0
  41. data/lib/opal/cli_runners/phantomjs.rb +28 -0
  42. data/lib/opal/cli_runners/server.rb +54 -0
  43. data/lib/opal/compiler.rb +307 -0
  44. data/lib/opal/erb.rb +64 -0
  45. data/lib/opal/fragment.rb +41 -0
  46. data/lib/opal/hike_path_finder.rb +18 -0
  47. data/lib/opal/nodes.rb +26 -0
  48. data/lib/opal/nodes/arglist.rb +56 -0
  49. data/lib/opal/nodes/array.rb +54 -0
  50. data/lib/opal/nodes/base.rb +151 -0
  51. data/lib/opal/nodes/call.rb +283 -0
  52. data/lib/opal/nodes/call_special.rb +178 -0
  53. data/lib/opal/nodes/case.rb +96 -0
  54. data/lib/opal/nodes/class.rb +42 -0
  55. data/lib/opal/nodes/constants.rb +78 -0
  56. data/lib/opal/nodes/def.rb +157 -0
  57. data/lib/opal/nodes/defined.rb +113 -0
  58. data/lib/opal/nodes/definitions.rb +168 -0
  59. data/lib/opal/nodes/for.rb +35 -0
  60. data/lib/opal/nodes/hash.rb +67 -0
  61. data/lib/opal/nodes/helpers.rb +114 -0
  62. data/lib/opal/nodes/if.rb +67 -0
  63. data/lib/opal/nodes/iter.rb +131 -0
  64. data/lib/opal/nodes/literal.rb +230 -0
  65. data/lib/opal/nodes/logic.rb +217 -0
  66. data/lib/opal/nodes/masgn.rb +62 -0
  67. data/lib/opal/nodes/module.rb +46 -0
  68. data/lib/opal/nodes/rescue.rb +135 -0
  69. data/lib/opal/nodes/runtime_helpers.rb +45 -0
  70. data/lib/opal/nodes/scope.rb +293 -0
  71. data/lib/opal/nodes/singleton_class.rb +25 -0
  72. data/lib/opal/nodes/super.rb +97 -0
  73. data/lib/opal/nodes/top.rb +101 -0
  74. data/lib/opal/nodes/variables.rb +158 -0
  75. data/lib/opal/nodes/while.rb +65 -0
  76. data/lib/opal/nodes/yield.rb +95 -0
  77. data/lib/opal/parser.rb +658 -0
  78. data/lib/opal/parser/grammar.rb +5452 -0
  79. data/lib/opal/parser/grammar.y +1684 -0
  80. data/lib/opal/parser/keywords.rb +66 -0
  81. data/lib/opal/parser/lexer.rb +1208 -0
  82. data/lib/opal/parser/parser_scope.rb +25 -0
  83. data/lib/opal/parser/sexp.rb +75 -0
  84. data/lib/opal/path_reader.rb +28 -0
  85. data/lib/opal/paths.rb +38 -0
  86. data/lib/opal/source_map.rb +70 -0
  87. data/lib/opal/sprockets.rb +4 -0
  88. data/lib/opal/sprockets/cache_key_fix.rb +17 -0
  89. data/lib/opal/sprockets/environment.rb +37 -0
  90. data/lib/opal/sprockets/erb.rb +37 -0
  91. data/lib/opal/sprockets/path_reader.rb +34 -0
  92. data/lib/opal/sprockets/processor.rb +124 -0
  93. data/lib/opal/sprockets/server.rb +180 -0
  94. data/lib/opal/util.rb +64 -0
  95. data/lib/opal/version.rb +3 -0
  96. data/opal.gemspec +36 -0
  97. data/opal/README.md +6 -0
  98. data/opal/corelib/array.rb +1556 -0
  99. data/opal/corelib/array/inheritance.rb +113 -0
  100. data/opal/corelib/basic_object.rb +73 -0
  101. data/opal/corelib/boolean.rb +41 -0
  102. data/opal/corelib/class.rb +55 -0
  103. data/opal/corelib/comparable.rb +56 -0
  104. data/opal/corelib/complex.rb +3 -0
  105. data/opal/corelib/dir.rb +20 -0
  106. data/opal/corelib/enumerable.rb +1132 -0
  107. data/opal/corelib/enumerator.rb +422 -0
  108. data/opal/corelib/error.rb +63 -0
  109. data/opal/corelib/file.rb +56 -0
  110. data/opal/corelib/hash.rb +728 -0
  111. data/opal/corelib/helpers.rb +102 -0
  112. data/opal/corelib/io.rb +59 -0
  113. data/opal/corelib/kernel.rb +569 -0
  114. data/opal/corelib/main.rb +7 -0
  115. data/opal/corelib/match_data.rb +114 -0
  116. data/opal/corelib/method.rb +58 -0
  117. data/opal/corelib/module.rb +462 -0
  118. data/opal/corelib/nil_class.rb +62 -0
  119. data/opal/corelib/numeric.rb +532 -0
  120. data/opal/corelib/proc.rb +52 -0
  121. data/opal/corelib/range.rb +116 -0
  122. data/opal/corelib/rational.rb +3 -0
  123. data/opal/corelib/regexp.rb +133 -0
  124. data/opal/corelib/runtime.js +1240 -0
  125. data/opal/corelib/string.rb +1212 -0
  126. data/opal/corelib/string/inheritance.rb +78 -0
  127. data/opal/corelib/struct.rb +141 -0
  128. data/opal/corelib/time.rb +584 -0
  129. data/opal/corelib/variables.rb +24 -0
  130. data/opal/opal.rb +32 -0
  131. data/package.json +9 -0
  132. data/spec/filters/bugs/array.rb +232 -0
  133. data/spec/filters/bugs/basic_object.rb +14 -0
  134. data/spec/filters/bugs/class.rb +21 -0
  135. data/spec/filters/bugs/enumerable.rb +69 -0
  136. data/spec/filters/bugs/enumerator.rb +3 -0
  137. data/spec/filters/bugs/hash.rb +128 -0
  138. data/spec/filters/bugs/kernel.rb +10 -0
  139. data/spec/filters/bugs/language.rb +415 -0
  140. data/spec/filters/bugs/math.rb +95 -0
  141. data/spec/filters/bugs/module.rb +14 -0
  142. data/spec/filters/bugs/nil.rb +7 -0
  143. data/spec/filters/bugs/numeric.rb +20 -0
  144. data/spec/filters/bugs/opal.rb +14 -0
  145. data/spec/filters/bugs/regexp.rb +11 -0
  146. data/spec/filters/bugs/set.rb +7 -0
  147. data/spec/filters/bugs/singleton.rb +6 -0
  148. data/spec/filters/bugs/string.rb +360 -0
  149. data/spec/filters/bugs/stringscanner.rb +22 -0
  150. data/spec/filters/bugs/struct.rb +45 -0
  151. data/spec/filters/bugs/time.rb +177 -0
  152. data/spec/filters/bugs/unknown.rb +11 -0
  153. data/spec/filters/unsupported/encoding.rb +95 -0
  154. data/spec/filters/unsupported/enumerator.rb +14 -0
  155. data/spec/filters/unsupported/float.rb +5 -0
  156. data/spec/filters/unsupported/frozen.rb +90 -0
  157. data/spec/filters/unsupported/hash_compare_by_identity.rb +16 -0
  158. data/spec/filters/unsupported/integer_size.rb +7 -0
  159. data/spec/filters/unsupported/method_added.rb +10 -0
  160. data/spec/filters/unsupported/mutable_strings.rb +361 -0
  161. data/spec/filters/unsupported/private_constants.rb +30 -0
  162. data/spec/filters/unsupported/private_methods.rb +44 -0
  163. data/spec/filters/unsupported/random.rb +4 -0
  164. data/spec/filters/unsupported/ruby_exe.rb +5 -0
  165. data/spec/filters/unsupported/tainted.rb +155 -0
  166. data/spec/filters/unsupported/time.rb +21 -0
  167. data/spec/filters/unsupported/trusted.rb +80 -0
  168. data/spec/lib/builder_processors_spec.rb +27 -0
  169. data/spec/lib/builder_spec.rb +66 -0
  170. data/spec/lib/cli_spec.rb +134 -0
  171. data/spec/lib/compiler_spec.rb +197 -0
  172. data/spec/lib/dependency_resolver_spec.rb +40 -0
  173. data/spec/lib/fixtures/no_requires.rb +1 -0
  174. data/spec/lib/fixtures/opal_file.rb +2 -0
  175. data/spec/lib/fixtures/require_tree_test.rb +3 -0
  176. data/spec/lib/fixtures/required_tree_test/required_file1.rb +1 -0
  177. data/spec/lib/fixtures/required_tree_test/required_file2.rb +1 -0
  178. data/spec/lib/fixtures/requires.rb +7 -0
  179. data/spec/lib/fixtures/sprockets_file.js.rb +3 -0
  180. data/spec/lib/fixtures/sprockets_require_tree_test.rb +3 -0
  181. data/spec/lib/hike_path_finder_spec.rb +23 -0
  182. data/spec/lib/lexer_spec.rb +110 -0
  183. data/spec/lib/parser/alias_spec.rb +26 -0
  184. data/spec/lib/parser/and_spec.rb +13 -0
  185. data/spec/lib/parser/attrasgn_spec.rb +28 -0
  186. data/spec/lib/parser/begin_spec.rb +42 -0
  187. data/spec/lib/parser/block_spec.rb +12 -0
  188. data/spec/lib/parser/break_spec.rb +17 -0
  189. data/spec/lib/parser/call_spec.rb +139 -0
  190. data/spec/lib/parser/class_spec.rb +35 -0
  191. data/spec/lib/parser/comments_spec.rb +11 -0
  192. data/spec/lib/parser/def_spec.rb +61 -0
  193. data/spec/lib/parser/if_spec.rb +26 -0
  194. data/spec/lib/parser/iter_spec.rb +59 -0
  195. data/spec/lib/parser/lambda_spec.rb +64 -0
  196. data/spec/lib/parser/literal_spec.rb +118 -0
  197. data/spec/lib/parser/masgn_spec.rb +37 -0
  198. data/spec/lib/parser/module_spec.rb +27 -0
  199. data/spec/lib/parser/not_spec.rb +27 -0
  200. data/spec/lib/parser/op_asgn1_spec.rb +23 -0
  201. data/spec/lib/parser/op_asgn2_spec.rb +23 -0
  202. data/spec/lib/parser/or_spec.rb +13 -0
  203. data/spec/lib/parser/return_spec.rb +17 -0
  204. data/spec/lib/parser/sclass_spec.rb +21 -0
  205. data/spec/lib/parser/string_spec.rb +276 -0
  206. data/spec/lib/parser/super_spec.rb +20 -0
  207. data/spec/lib/parser/unary_spec.rb +48 -0
  208. data/spec/lib/parser/undef_spec.rb +15 -0
  209. data/spec/lib/parser/unless_spec.rb +13 -0
  210. data/spec/lib/parser/variables_spec.rb +92 -0
  211. data/spec/lib/parser/while_spec.rb +15 -0
  212. data/spec/lib/parser/yield_spec.rb +20 -0
  213. data/spec/lib/path_reader_spec.rb +24 -0
  214. data/spec/lib/shared/path_finder_shared.rb +19 -0
  215. data/spec/lib/shared/path_reader_shared.rb +31 -0
  216. data/spec/lib/spec_helper.rb +9 -0
  217. data/spec/lib/sprockets/environment_spec.rb +30 -0
  218. data/spec/lib/sprockets/erb_spec.rb +25 -0
  219. data/spec/lib/sprockets/path_reader_spec.rb +25 -0
  220. data/spec/lib/sprockets/processor_spec.rb +35 -0
  221. data/spec/lib/sprockets/server_spec.rb +20 -0
  222. data/spec/opal/compiler/irb_spec.rb +44 -0
  223. data/spec/opal/core/array/select_spec.rb +14 -0
  224. data/spec/opal/core/array/set_range_to_array_spec.rb +7 -0
  225. data/spec/opal/core/date_spec.rb +122 -0
  226. data/spec/opal/core/enumerable/all_break_spec.rb +5 -0
  227. data/spec/opal/core/enumerable/any_break_spec.rb +5 -0
  228. data/spec/opal/core/enumerable/collect_break_spec.rb +13 -0
  229. data/spec/opal/core/enumerable/count_break_spec.rb +5 -0
  230. data/spec/opal/core/enumerable/detect_break_spec.rb +5 -0
  231. data/spec/opal/core/enumerable/drop_while_break_spec.rb +5 -0
  232. data/spec/opal/core/enumerable/each_slice_break.rb +6 -0
  233. data/spec/opal/core/enumerable/each_with_index_break_spec.rb +5 -0
  234. data/spec/opal/core/enumerable/each_with_object_break_spec.rb +5 -0
  235. data/spec/opal/core/enumerable/find_all_break_spec.rb +5 -0
  236. data/spec/opal/core/enumerable/find_index_break_spec.rb +5 -0
  237. data/spec/opal/core/enumerable/grep_break_spec.rb +5 -0
  238. data/spec/opal/core/enumerable/max_break_spec.rb +5 -0
  239. data/spec/opal/core/enumerable/max_by_break_spec.rb +5 -0
  240. data/spec/opal/core/enumerable/min_break_spec.rb +5 -0
  241. data/spec/opal/core/enumerable/min_by_break_spec.rb +5 -0
  242. data/spec/opal/core/enumerable/none_break_spec.rb +5 -0
  243. data/spec/opal/core/enumerable/one_break_spec.rb +5 -0
  244. data/spec/opal/core/enumerable/reduce_break_spec.rb +5 -0
  245. data/spec/opal/core/enumerable/take_while_break_spec.rb +5 -0
  246. data/spec/opal/core/fixtures/class.rb +124 -0
  247. data/spec/opal/core/fixtures/class_variables.rb +0 -0
  248. data/spec/opal/core/fixtures/constants.rb +33 -0
  249. data/spec/opal/core/fixtures/require_tree_files/file 1.rb +1 -0
  250. data/spec/opal/core/fixtures/require_tree_files/file 2.rb +1 -0
  251. data/spec/opal/core/fixtures/require_tree_files/file 3.rb +1 -0
  252. data/spec/opal/core/fixtures/require_tree_files/file 4.rb +1 -0
  253. data/spec/opal/core/fixtures/require_tree_files/file 5.rb +1 -0
  254. data/spec/opal/core/kernel/Array_spec.rb +10 -0
  255. data/spec/opal/core/kernel/block_given_spec.rb +30 -0
  256. data/spec/opal/core/kernel/class_spec.rb +6 -0
  257. data/spec/opal/core/kernel/define_singleton_method_spec.rb +21 -0
  258. data/spec/opal/core/kernel/equal_value_spec.rb +12 -0
  259. data/spec/opal/core/kernel/extend_spec.rb +21 -0
  260. data/spec/opal/core/kernel/format_spec.rb +122 -0
  261. data/spec/opal/core/kernel/freeze_spec.rb +15 -0
  262. data/spec/opal/core/kernel/instance_eval_spec.rb +28 -0
  263. data/spec/opal/core/kernel/instance_variable_defined_spec.rb +15 -0
  264. data/spec/opal/core/kernel/instance_variable_get_spec.rb +14 -0
  265. data/spec/opal/core/kernel/instance_variable_set_spec.rb +10 -0
  266. data/spec/opal/core/kernel/loop_spec.rb +23 -0
  267. data/spec/opal/core/kernel/match_spec.rb +5 -0
  268. data/spec/opal/core/kernel/method_spec.rb +31 -0
  269. data/spec/opal/core/kernel/methods_spec.rb +25 -0
  270. data/spec/opal/core/kernel/nil_spec.rb +7 -0
  271. data/spec/opal/core/kernel/p_spec.rb +15 -0
  272. data/spec/opal/core/kernel/printf_spec.rb +11 -0
  273. data/spec/opal/core/kernel/proc_spec.rb +13 -0
  274. data/spec/opal/core/kernel/rand_spec.rb +23 -0
  275. data/spec/opal/core/kernel/require_tree_spec.rb +7 -0
  276. data/spec/opal/core/kernel/respond_to_spec.rb +41 -0
  277. data/spec/opal/core/kernel/send_spec.rb +56 -0
  278. data/spec/opal/core/kernel/sprintf_spec.rb +5 -0
  279. data/spec/opal/core/language/block_spec.rb +538 -0
  280. data/spec/opal/core/language/fixtures/array.rb +11 -0
  281. data/spec/opal/core/language/fixtures/block.rb +57 -0
  282. data/spec/opal/core/language/fixtures/break.rb +240 -0
  283. data/spec/opal/core/language/fixtures/ensure.rb +72 -0
  284. data/spec/opal/core/language/fixtures/literal_lambda.rb +7 -0
  285. data/spec/opal/core/language/fixtures/metaclass.rb +33 -0
  286. data/spec/opal/core/language/fixtures/module.rb +24 -0
  287. data/spec/opal/core/language/fixtures/next.rb +128 -0
  288. data/spec/opal/core/language/fixtures/return.rb +118 -0
  289. data/spec/opal/core/language/fixtures/send.rb +110 -0
  290. data/spec/opal/core/language/fixtures/send_1.9.rb +22 -0
  291. data/spec/opal/core/language/fixtures/super.rb +308 -0
  292. data/spec/opal/core/language/fixtures/variables.rb +58 -0
  293. data/spec/opal/core/language/fixtures/yield.rb +28 -0
  294. data/spec/opal/core/language/predefined_spec.rb +85 -0
  295. data/spec/opal/core/language/proc_spec.rb +263 -0
  296. data/spec/opal/core/language/regexp_spec.rb +20 -0
  297. data/spec/opal/core/language/send_spec.rb +225 -0
  298. data/spec/opal/core/language/string_spec.rb +44 -0
  299. data/spec/opal/core/language/symbol_spec.rb +40 -0
  300. data/spec/opal/core/language/variables_spec.rb +1366 -0
  301. data/spec/opal/core/language/versions/array_1.9.rb +39 -0
  302. data/spec/opal/core/language/versions/block_1.9.rb +0 -0
  303. data/spec/opal/core/language/versions/break_1.9.rb +0 -0
  304. data/spec/opal/core/language/versions/case_1.9.rb +20 -0
  305. data/spec/opal/core/language/versions/hash_1.9.rb +18 -0
  306. data/spec/opal/core/language/versions/literal_lambda_1.9.rb +143 -0
  307. data/spec/opal/core/language/versions/not_1.9.rb +22 -0
  308. data/spec/opal/core/language/versions/send_1.9.rb +241 -0
  309. data/spec/opal/core/language/versions/symbol_1.9.rb +15 -0
  310. data/spec/opal/core/language/versions/variables_1.9.rb +8 -0
  311. data/spec/opal/core/module/alias_method_spec.rb +28 -0
  312. data/spec/opal/core/module/ancestors_spec.rb +11 -0
  313. data/spec/opal/core/module/append_features_spec.rb +14 -0
  314. data/spec/opal/core/module/attr_accessor_spec.rb +26 -0
  315. data/spec/opal/core/module/const_defined_spec.rb +85 -0
  316. data/spec/opal/core/module/const_get_spec.rb +85 -0
  317. data/spec/opal/core/module/const_missing_spec.rb +17 -0
  318. data/spec/opal/core/module/const_set_spec.rb +64 -0
  319. data/spec/opal/core/module/constants_spec.rb +49 -0
  320. data/spec/opal/core/module/fixtures/classes.rb +434 -0
  321. data/spec/opal/core/module/method_defined_spec.rb +48 -0
  322. data/spec/opal/core/module/module_function_spec.rb +25 -0
  323. data/spec/opal/core/module/name_spec.rb +52 -0
  324. data/spec/opal/core/module/public_method_defined_spec.rb +18 -0
  325. data/spec/opal/core/module/remove_const_spec.rb +22 -0
  326. data/spec/opal/core/module/undef_method_spec.rb +66 -0
  327. data/spec/opal/core/numeric/bit_and_spec.rb +7 -0
  328. data/spec/opal/core/numeric/bit_or_spec.rb +8 -0
  329. data/spec/opal/core/numeric/bit_xor_spec.rb +6 -0
  330. data/spec/opal/core/numeric/ceil_spec.rb +8 -0
  331. data/spec/opal/core/numeric/chr_spec.rb +8 -0
  332. data/spec/opal/core/numeric/comparison_spec.rb +24 -0
  333. data/spec/opal/core/numeric/complement_spec.rb +8 -0
  334. data/spec/opal/core/numeric/divide_spec.rb +10 -0
  335. data/spec/opal/core/numeric/eql_spec.rb +9 -0
  336. data/spec/opal/core/numeric/exponent_spec.rb +33 -0
  337. data/spec/opal/core/numeric/floor_spec.rb +8 -0
  338. data/spec/opal/core/numeric/gt_spec.rb +11 -0
  339. data/spec/opal/core/numeric/gte_spec.rb +12 -0
  340. data/spec/opal/core/numeric/integer_spec.rb +9 -0
  341. data/spec/opal/core/numeric/left_shift_spec.rb +21 -0
  342. data/spec/opal/core/numeric/lt_spec.rb +11 -0
  343. data/spec/opal/core/numeric/lte_spec.rb +12 -0
  344. data/spec/opal/core/numeric/minus_spec.rb +8 -0
  345. data/spec/opal/core/numeric/modulo_spec.rb +19 -0
  346. data/spec/opal/core/numeric/multiply_spec.rb +9 -0
  347. data/spec/opal/core/numeric/next_spec.rb +9 -0
  348. data/spec/opal/core/numeric/ord_spec.rb +9 -0
  349. data/spec/opal/core/numeric/plus_spec.rb +8 -0
  350. data/spec/opal/core/numeric/pred_spec.rb +7 -0
  351. data/spec/opal/core/numeric/right_shift_spec.rb +25 -0
  352. data/spec/opal/core/numeric/step_spec.rb +11 -0
  353. data/spec/opal/core/numeric/succ_spec.rb +9 -0
  354. data/spec/opal/core/numeric/times_spec.rb +36 -0
  355. data/spec/opal/core/numeric/to_f_spec.rb +7 -0
  356. data/spec/opal/core/numeric/to_i_spec.rb +7 -0
  357. data/spec/opal/core/numeric/to_json_spec.rb +8 -0
  358. data/spec/opal/core/numeric/to_s_spec.rb +26 -0
  359. data/spec/opal/core/numeric/uminus_spec.rb +9 -0
  360. data/spec/opal/core/numeric/upto_spec.rb +19 -0
  361. data/spec/opal/core/numeric/zero_spec.rb +7 -0
  362. data/spec/opal/core/proc/call_spec.rb +21 -0
  363. data/spec/opal/core/proc/element_reference_spec.rb +21 -0
  364. data/spec/opal/core/proc/proc_tricks_spec.rb +7 -0
  365. data/spec/opal/core/runtime/begin_spec.rb +39 -0
  366. data/spec/opal/core/runtime/block_send_spec.rb +28 -0
  367. data/spec/opal/core/runtime/block_spec.rb +23 -0
  368. data/spec/opal/core/runtime/bridged_classes_spec.rb +64 -0
  369. data/spec/opal/core/runtime/constants_spec.rb +13 -0
  370. data/spec/opal/core/runtime/eval_spec.rb +5 -0
  371. data/spec/opal/core/runtime/main_methods_spec.rb +27 -0
  372. data/spec/opal/core/runtime/method_missing_spec.rb +62 -0
  373. data/spec/opal/core/runtime/method_spec.rb +31 -0
  374. data/spec/opal/core/runtime/operator_call_spec.rb +13 -0
  375. data/spec/opal/core/runtime/paren_spec.rb +14 -0
  376. data/spec/opal/core/runtime/rescue_spec.rb +38 -0
  377. data/spec/opal/core/runtime/return_spec.rb +38 -0
  378. data/spec/opal/core/runtime/send_spec.rb +34 -0
  379. data/spec/opal/core/runtime/singleton_class_spec.rb +13 -0
  380. data/spec/opal/core/runtime/super_spec.rb +212 -0
  381. data/spec/opal/core/runtime/truthy_spec.rb +23 -0
  382. data/spec/opal/core/runtime/variables_spec.rb +20 -0
  383. data/spec/opal/core/source_map_spec.rb +15 -0
  384. data/spec/opal/core/string_spec.rb +11 -0
  385. data/spec/opal/stdlib/erb/erb_spec.rb +30 -0
  386. data/spec/opal/stdlib/erb/inline_block.opalerb +3 -0
  387. data/spec/opal/stdlib/erb/quoted.opalerb +1 -0
  388. data/spec/opal/stdlib/erb/simple.opalerb +1 -0
  389. data/spec/opal/stdlib/json/ext_spec.rb +48 -0
  390. data/spec/opal/stdlib/json/parse_spec.rb +33 -0
  391. data/spec/opal/stdlib/native/alias_native_spec.rb +27 -0
  392. data/spec/opal/stdlib/native/each_spec.rb +13 -0
  393. data/spec/opal/stdlib/native/element_reference_spec.rb +16 -0
  394. data/spec/opal/stdlib/native/exposure_spec.rb +33 -0
  395. data/spec/opal/stdlib/native/ext_spec.rb +19 -0
  396. data/spec/opal/stdlib/native/initialize_spec.rb +17 -0
  397. data/spec/opal/stdlib/native/method_missing_spec.rb +51 -0
  398. data/spec/opal/stdlib/native/native_reader_spec.rb +22 -0
  399. data/spec/opal/stdlib/native/native_writer_spec.rb +30 -0
  400. data/spec/opal/stdlib/native/new_spec.rb +8 -0
  401. data/spec/opal/stdlib/promise/error_spec.rb +15 -0
  402. data/spec/opal/stdlib/promise/rescue_spec.rb +35 -0
  403. data/spec/opal/stdlib/promise/then_spec.rb +54 -0
  404. data/spec/opal/stdlib/promise/trace_spec.rb +35 -0
  405. data/spec/opal/stdlib/promise/value_spec.rb +15 -0
  406. data/spec/opal/stdlib/promise/when_spec.rb +34 -0
  407. data/spec/opal/stdlib/template/paths_spec.rb +10 -0
  408. data/spec/opal/stdlib/thread/mutex_spec.rb +40 -0
  409. data/spec/opal/stdlib/thread/thread_queue_spec.rb +32 -0
  410. data/spec/opal/stdlib/thread/thread_spec.rb +60 -0
  411. data/spec/rubyspecs +329 -0
  412. data/spec/spec_helper.rb +42 -0
  413. data/spec/support/mspec_rspec_adapter.rb +33 -0
  414. data/spec/support/parser_helpers.rb +37 -0
  415. data/stdlib/README.md +3 -0
  416. data/stdlib/base64.rb +152 -0
  417. data/stdlib/benchmark.rb +10 -0
  418. data/stdlib/buffer.rb +40 -0
  419. data/stdlib/buffer/array.rb +66 -0
  420. data/stdlib/buffer/view.rb +70 -0
  421. data/stdlib/date.rb +170 -0
  422. data/stdlib/delegate.rb +29 -0
  423. data/stdlib/dir.rb +1 -0
  424. data/stdlib/encoding.rb +166 -0
  425. data/stdlib/enumerator.rb +1 -0
  426. data/stdlib/erb.rb +16 -0
  427. data/stdlib/file.rb +1 -0
  428. data/stdlib/forwardable.rb +71 -0
  429. data/stdlib/json.rb +182 -0
  430. data/stdlib/math.rb +370 -0
  431. data/stdlib/native.rb +530 -0
  432. data/stdlib/nodejs.rb +5 -0
  433. data/stdlib/nodejs/dir.rb +13 -0
  434. data/stdlib/nodejs/file.rb +98 -0
  435. data/stdlib/nodejs/fileutils.rb +26 -0
  436. data/stdlib/nodejs/io.rb +2 -0
  437. data/stdlib/nodejs/irb.rb +45 -0
  438. data/stdlib/nodejs/process.rb +16 -0
  439. data/stdlib/nodejs/require.rb +32 -0
  440. data/stdlib/nodejs/rubygems.rb +68 -0
  441. data/stdlib/nodejs/runtime.rb +25 -0
  442. data/stdlib/nodejs/yaml.rb +11 -0
  443. data/stdlib/observer.rb +202 -0
  444. data/stdlib/opal-parser.rb +53 -0
  445. data/stdlib/opal-source-maps.rb +2 -0
  446. data/stdlib/ostruct.rb +69 -0
  447. data/stdlib/pathname.rb +31 -0
  448. data/stdlib/phantomjs.rb +8 -0
  449. data/stdlib/pp.rb +12 -0
  450. data/stdlib/process.rb +10 -0
  451. data/stdlib/promise.rb +300 -0
  452. data/stdlib/racc/parser.rb +215 -0
  453. data/stdlib/rbconfig.rb +20 -0
  454. data/stdlib/securerandom.rb +12 -0
  455. data/stdlib/set.rb +116 -0
  456. data/stdlib/singleton.rb +40 -0
  457. data/stdlib/source_map.rb +5 -0
  458. data/stdlib/source_map/map.rb +220 -0
  459. data/stdlib/source_map/mapping.rb +26 -0
  460. data/stdlib/source_map/offset.rb +88 -0
  461. data/stdlib/source_map/version.rb +3 -0
  462. data/stdlib/source_map/vlq.rb +98 -0
  463. data/stdlib/sourcemap.rb +1 -0
  464. data/stdlib/stringio.rb +181 -0
  465. data/stdlib/strscan.rb +155 -0
  466. data/stdlib/template.rb +46 -0
  467. data/stdlib/thread.rb +160 -0
  468. data/stdlib/time.rb +9 -0
  469. data/tasks/github.rake +19 -0
  470. metadata +690 -0
@@ -0,0 +1,180 @@
1
+ require 'rack/file'
2
+ require 'rack/static'
3
+ require 'rack/urlmap'
4
+ require 'rack/builder'
5
+ require 'rack/deflater'
6
+ require 'rack/directory'
7
+ require 'rack/showexceptions'
8
+ require 'opal/source_map'
9
+ require 'opal/sprockets/environment'
10
+ require 'erb'
11
+
12
+ module Opal
13
+
14
+ class SourceMapServer
15
+ def initialize sprockets, prefix = '/'
16
+ @sprockets = sprockets
17
+ @prefix = prefix
18
+ end
19
+
20
+ attr_reader :sprockets, :prefix
21
+
22
+ def inspect
23
+ "#<#{self.class}:#{object_id}>"
24
+ end
25
+
26
+ def call(env)
27
+ prefix_regex = %r{^(?:#{prefix}/|/)}
28
+ path_info = env['PATH_INFO'].to_s.sub(prefix_regex, '')
29
+
30
+ case path_info
31
+ when %r{^(.*)\.map$}
32
+ path = $1
33
+ asset = sprockets[path]
34
+ return not_found(path) if asset.nil?
35
+
36
+ # "logical_name" of a BundledAsset keeps the .js extension
37
+ source = register[asset.logical_path.sub(/\.js$/, '')]
38
+ return not_found(asset) if source.nil?
39
+
40
+ return [200, {"Content-Type" => "text/json"}, [source.to_s]]
41
+ when %r{^(.*)\.rb$}
42
+ source = File.read(sprockets.resolve(path_info))
43
+ return not_found(path_info) if source.nil?
44
+ return [200, {"Content-Type" => "text/ruby"}, [source]]
45
+ else
46
+ not_found(path_info)
47
+ end
48
+ end
49
+
50
+ def not_found(*messages)
51
+ not_found = [404, {}, [{not_found: messages, keys: register.keys}.inspect]]
52
+ end
53
+
54
+ def register
55
+ Opal::Processor.source_map_register
56
+ end
57
+ end
58
+
59
+ class Server
60
+
61
+ attr_accessor :debug, :use_index, :index_path, :main, :public_root,
62
+ :public_urls, :sprockets, :prefix
63
+
64
+ def initialize debug_or_options = {}
65
+ unless Hash === debug_or_options
66
+ warn "passing a boolean to control debug is deprecated.\n"+
67
+ "Please pass an Hash instead: Server.new(debug: true)"
68
+ options = {:debug => debug_or_options}
69
+ else
70
+ options = debug_or_options
71
+ end
72
+
73
+ @use_index = true
74
+ @public_root = nil
75
+ @public_urls = ['/']
76
+ @sprockets = options.fetch(:sprockets, Environment.new)
77
+ @debug = options.fetch(:debug, true)
78
+ @prefix = options.fetch(:prefix, '/assets')
79
+
80
+ yield self if block_given?
81
+ create_app
82
+ end
83
+
84
+ def public_dir=(dir)
85
+ @public_root = dir
86
+ @public_urls = ["/"]
87
+ end
88
+
89
+ def source_map=(enabled)
90
+ Opal::Processor.source_map_enabled = enabled
91
+ end
92
+
93
+ def source_map_enabled
94
+ Opal::Processor.source_map_enabled
95
+ end
96
+
97
+ def append_path path
98
+ @sprockets.append_path path
99
+ end
100
+
101
+ def use_gem gem_name
102
+ @sprockets.use_gem gem_name
103
+ end
104
+
105
+ def create_app
106
+ server, sprockets, prefix = self, @sprockets, self.prefix
107
+ sprockets.logger.level ||= Logger::DEBUG
108
+ @app = Rack::Builder.app do
109
+ not_found = lambda { |env| [404, {}, []] }
110
+ use Rack::Deflater
111
+ use Rack::ShowExceptions
112
+ use Index, server if server.use_index
113
+ assets = []
114
+ assets << SourceMapServer.new(sprockets, prefix) if server.source_map_enabled
115
+ assets << sprockets
116
+ map(prefix) { run Rack::Cascade.new(assets) }
117
+ run Rack::Static.new(not_found, :root => server.public_root, :urls => server.public_urls)
118
+ end
119
+ end
120
+
121
+ def call(env)
122
+ @app.call env
123
+ end
124
+
125
+ class Index
126
+
127
+ def initialize(app, server)
128
+ @app = app
129
+ @server = server
130
+ @index_path = server.index_path
131
+ end
132
+
133
+ def call(env)
134
+ if %w[/ /index.html].include? env['PATH_INFO']
135
+ [200, { 'Content-Type' => 'text/html' }, [html]]
136
+ else
137
+ @app.call env
138
+ end
139
+ end
140
+
141
+ # Returns the html content for the root path. Supports ERB
142
+ def html
143
+ if @index_path
144
+ raise "index does not exist: #{@index_path}" unless File.exist?(@index_path)
145
+ Tilt.new(@index_path).render(self)
146
+ else
147
+ ::ERB.new(SOURCE).result binding
148
+ end
149
+ end
150
+
151
+ def javascript_include_tag source
152
+ if @server.debug
153
+ assets = @server.sprockets[source].to_a
154
+
155
+ raise "Cannot find asset: #{source}" if assets.empty?
156
+
157
+ scripts = assets.map do |a|
158
+ %Q{<script src="/assets/#{ a.logical_path }?body=1"></script>}
159
+ end
160
+
161
+ scripts.join "\n"
162
+ else
163
+ "<script src=\"/assets/#{source}.js\"></script>"
164
+ end
165
+ end
166
+
167
+ SOURCE = <<-HTML
168
+ <!DOCTYPE html>
169
+ <html>
170
+ <head>
171
+ <title>Opal Server</title>
172
+ </head>
173
+ <body>
174
+ <%= javascript_include_tag @server.main %>
175
+ </body>
176
+ </html>
177
+ HTML
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,64 @@
1
+ module Opal
2
+ module Util
3
+ extend self
4
+
5
+ # Used for uglifying source to minify
6
+ def uglify(str)
7
+ uglifyjs = DigestSourceCommand.new(:uglifyjs, nil, ' (install with: "npm install -g uglify-js")')
8
+ uglifyjs.digest(str)
9
+ end
10
+
11
+ # Gzip code to check file size
12
+ def gzip(str)
13
+ gzip = DigestSourceCommand.new(:gzip, '-f', ', it is required to produce the .gz version')
14
+ gzip.digest(str)
15
+ end
16
+
17
+ class Command
18
+ def initialize(command, options, message = nil)
19
+ @command, @options, @message = command, options, message
20
+ return unless command_installed? command, message
21
+ end
22
+ attr_reader :command, :options, :message
23
+
24
+ private
25
+
26
+ def hide_stderr
27
+ if (/mswin|mingw/ =~ RUBY_PLATFORM).nil?
28
+ '2> /dev/null'
29
+ else
30
+ '2> nul'
31
+ end
32
+ end
33
+
34
+ # Code from http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
35
+ def which(cmd)
36
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
37
+ ENV['PATH'].split(File::PATH_SEPARATOR).find do |path|
38
+ exts.find { |ext|
39
+ exe = File.join(path, "#{cmd}#{ext}")
40
+ exe if File.executable? exe
41
+ }
42
+ end
43
+ end
44
+
45
+ INSTALLED = {}
46
+ def command_installed?(cmd, install_comment)
47
+ command_installed = Command::INSTALLED[cmd.to_s] ||= which(cmd)
48
+ $stderr.puts %Q("#{cmd}" command not found#{install_comment}) unless command_installed
49
+ command_installed
50
+ end
51
+ end
52
+
53
+ class DigestSourceCommand < Command
54
+ def digest(source)
55
+ IO.popen("#{command} #{options} #{hide_stderr}", 'r+') do |i|
56
+ i.puts source
57
+ i.close_write
58
+ i.read
59
+ end
60
+ end
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,3 @@
1
+ module Opal
2
+ VERSION = '0.7.0.beta1'
3
+ end
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'opal/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'opal-cj'
8
+ s.version = Opal::VERSION
9
+ s.author = 'Adam Beynon'
10
+ s.email = 'adam.beynon@gmail.com'
11
+ s.homepage = 'http://opalrb.org'
12
+ s.summary = 'Ruby runtime and core library for javascript'
13
+ s.description = 'Ruby runtime and core library for javascript.'
14
+ s.license = 'MIT'
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.require_paths = ['lib']
20
+
21
+ required_ruby_version = '>= 1.9.3'
22
+
23
+ s.add_dependency 'sourcemap', '~> 0.1.0'
24
+ s.add_dependency 'sprockets', '>= 2.2.1', '< 4.0.0'
25
+ s.add_dependency 'hike', '~> 1.2'
26
+ s.add_dependency 'tilt', '~> 1.4'
27
+
28
+ s.add_development_dependency 'mspec', '1.5.20'
29
+ s.add_development_dependency 'rake'
30
+ s.add_development_dependency 'racc'
31
+ s.add_development_dependency 'rspec', '~> 2.99'
32
+ s.add_development_dependency 'octokit', '~> 2.4.0'
33
+ s.add_development_dependency 'bundler', '~> 1.5'
34
+ s.add_development_dependency 'yard', '~> 0.8.7'
35
+ s.add_development_dependency 'rack-test'
36
+ end
@@ -0,0 +1,6 @@
1
+ # Opal corelib
2
+
3
+ This is the Opal corelib implementation API documentation.
4
+ The whole corelib is loaded upon `require 'opal'`.
5
+
6
+ The `runtime.js` documentation is [availble here](runtime.js.html)
@@ -0,0 +1,1556 @@
1
+ require 'corelib/enumerable'
2
+
3
+ class Array
4
+ include Enumerable
5
+
6
+ # Mark all javascript arrays as being valid ruby arrays
7
+ `def.$$is_array = true`
8
+
9
+ def self.[](*objects)
10
+ objects
11
+ end
12
+
13
+ def initialize(*args)
14
+ self.class.new(*args)
15
+ end
16
+
17
+ def self.new(size = nil, obj = nil, &block)
18
+ if `arguments.length > 2`
19
+ raise ArgumentError, "wrong number of arguments (#{`arguments.length`} for 0..2)"
20
+ end
21
+
22
+ if `arguments.length === 0`
23
+ return []
24
+ end
25
+
26
+ if `arguments.length === 1`
27
+ if Array === size
28
+ return size.to_a
29
+ elsif size.respond_to? :to_ary
30
+ return size.to_ary
31
+ end
32
+ end
33
+
34
+ size = Opal.coerce_to size, Integer, :to_int
35
+
36
+ if `size < 0`
37
+ raise ArgumentError, "negative array size"
38
+ end
39
+
40
+ %x{
41
+ var result = [];
42
+
43
+ if (block === nil) {
44
+ for (var i = 0; i < size; i++) {
45
+ result.push(obj);
46
+ }
47
+ }
48
+ else {
49
+ for (var i = 0, value; i < size; i++) {
50
+ value = block(i);
51
+
52
+ if (value === $breaker) {
53
+ return $breaker.$v;
54
+ }
55
+
56
+ result[i] = value;
57
+ }
58
+ }
59
+
60
+ return result;
61
+ }
62
+ end
63
+
64
+ def self.try_convert(obj)
65
+ Opal.coerce_to? obj, Array, :to_ary
66
+ end
67
+
68
+ def &(other)
69
+ if Array === other
70
+ other = other.to_a
71
+ else
72
+ other = Opal.coerce_to(other, Array, :to_ary).to_a
73
+ end
74
+
75
+ %x{
76
+ var result = [],
77
+ seen = {};
78
+
79
+ for (var i = 0, length = self.length; i < length; i++) {
80
+ var item = self[i];
81
+
82
+ if (!seen[item]) {
83
+ for (var j = 0, length2 = other.length; j < length2; j++) {
84
+ var item2 = other[j];
85
+
86
+ if (!seen[item2] && #{`item` == `item2`}) {
87
+ seen[item] = true;
88
+ result.push(item);
89
+ }
90
+ }
91
+ }
92
+ }
93
+
94
+ return result;
95
+ }
96
+ end
97
+
98
+ def |(other)
99
+ if Array === other
100
+ other = other.to_a
101
+ else
102
+ other = Opal.coerce_to(other, Array, :to_ary).to_a
103
+ end
104
+
105
+ %x{
106
+ var result = [],
107
+ seen = {};
108
+
109
+ for (var i = 0, length = self.length; i < length; i++) {
110
+ var item = self[i];
111
+
112
+ if (!seen[item]) {
113
+ seen[item] = true;
114
+ result.push(item);
115
+ }
116
+ }
117
+
118
+ for (var i = 0, length = other.length; i < length; i++) {
119
+ var item = other[i];
120
+
121
+ if (!seen[item]) {
122
+ seen[item] = true;
123
+ result.push(item);
124
+ }
125
+ }
126
+ return result;
127
+ }
128
+ end
129
+
130
+ def *(other)
131
+ return `self.join(#{other.to_str})` if other.respond_to? :to_str
132
+
133
+ unless other.respond_to? :to_int
134
+ raise TypeError, "no implicit conversion of #{other.class} into Integer"
135
+ end
136
+
137
+ other = Opal.coerce_to other, Integer, :to_int
138
+
139
+ if `other < 0`
140
+ raise ArgumentError, "negative argument"
141
+ end
142
+
143
+ %x{
144
+ var result = [];
145
+
146
+ for (var i = 0; i < other; i++) {
147
+ result = result.concat(self);
148
+ }
149
+
150
+ return result;
151
+ }
152
+ end
153
+
154
+ def +(other)
155
+ if Array === other
156
+ other = other.to_a
157
+ else
158
+ other = Opal.coerce_to(other, Array, :to_ary).to_a
159
+ end
160
+
161
+ `self.concat(other)`
162
+ end
163
+
164
+ def -(other)
165
+ if Array === other
166
+ other = other.to_a
167
+ else
168
+ other = Opal.coerce_to(other, Array, :to_ary).to_a
169
+ end
170
+
171
+ return [] if `self.length === 0`
172
+ return clone if `other.length === 0`
173
+
174
+ %x{
175
+ var seen = {},
176
+ result = [];
177
+
178
+ for (var i = 0, length = other.length; i < length; i++) {
179
+ seen[other[i]] = true;
180
+ }
181
+
182
+ for (var i = 0, length = self.length; i < length; i++) {
183
+ var item = self[i];
184
+
185
+ if (!seen[item]) {
186
+ result.push(item);
187
+ }
188
+ }
189
+
190
+ return result;
191
+ }
192
+ end
193
+
194
+ def <<(object)
195
+ `self.push(object);`
196
+
197
+ self
198
+ end
199
+
200
+ def <=>(other)
201
+ if Array === other
202
+ other = other.to_a
203
+ elsif other.respond_to? :to_ary
204
+ other = other.to_ary.to_a
205
+ else
206
+ return
207
+ end
208
+
209
+ %x{
210
+ if (#{hash} === #{other.hash}) {
211
+ return 0;
212
+ }
213
+
214
+ if (self.length != other.length) {
215
+ return (self.length > other.length) ? 1 : -1;
216
+ }
217
+
218
+ for (var i = 0, length = self.length; i < length; i++) {
219
+ var tmp = #{`self[i]` <=> `other[i]`};
220
+
221
+ if (tmp !== 0) {
222
+ return tmp;
223
+ }
224
+ }
225
+
226
+ return 0;
227
+ }
228
+ end
229
+
230
+ def ==(other)
231
+ return true if `self === other`
232
+
233
+ unless Array === other
234
+ return false unless other.respond_to? :to_ary
235
+ return other == self
236
+ end
237
+
238
+ other = other.to_a
239
+
240
+ return false unless `self.length === other.length`
241
+
242
+ %x{
243
+ for (var i = 0, length = self.length; i < length; i++) {
244
+ var a = self[i],
245
+ b = other[i];
246
+
247
+ if (a.$$is_array && b.$$is_array && (a === self)) {
248
+ continue;
249
+ }
250
+
251
+ if (!#{`a` == `b`}) {
252
+ return false;
253
+ }
254
+ }
255
+ }
256
+
257
+ true
258
+ end
259
+
260
+ def [](index, length = undefined)
261
+ if Range === index
262
+ %x{
263
+ var size = self.length,
264
+ exclude = index.exclude,
265
+ from = #{Opal.coerce_to `index.begin`, Integer, :to_int},
266
+ to = #{Opal.coerce_to `index.end`, Integer, :to_int};
267
+
268
+ if (from < 0) {
269
+ from += size;
270
+
271
+ if (from < 0) {
272
+ return nil;
273
+ }
274
+ }
275
+
276
+ if (from > size) {
277
+ return nil;
278
+ }
279
+
280
+ if (to < 0) {
281
+ to += size;
282
+
283
+ if (to < 0) {
284
+ return [];
285
+ }
286
+ }
287
+
288
+ if (!exclude) {
289
+ to += 1;
290
+ }
291
+
292
+ return self.slice(from, to);
293
+ }
294
+ else
295
+ index = Opal.coerce_to index, Integer, :to_int
296
+
297
+ %x{
298
+ var size = self.length;
299
+
300
+ if (index < 0) {
301
+ index += size;
302
+
303
+ if (index < 0) {
304
+ return nil;
305
+ }
306
+ }
307
+
308
+ if (length === undefined) {
309
+ if (index >= size || index < 0) {
310
+ return nil;
311
+ }
312
+
313
+ return self[index];
314
+ }
315
+ else {
316
+ length = #{Opal.coerce_to length, Integer, :to_int};
317
+
318
+ if (length < 0 || index > size || index < 0) {
319
+ return nil;
320
+ }
321
+
322
+ return self.slice(index, index + length);
323
+ }
324
+ }
325
+ end
326
+ end
327
+
328
+ def []=(index, value, extra = undefined)
329
+ if Range === index
330
+ if Array === value
331
+ data = value.to_a
332
+ elsif value.respond_to? :to_ary
333
+ data = value.to_ary.to_a
334
+ else
335
+ data = [value]
336
+ end
337
+
338
+ %x{
339
+ var size = self.length,
340
+ exclude = index.exclude,
341
+ from = #{Opal.coerce_to `index.begin`, Integer, :to_int},
342
+ to = #{Opal.coerce_to `index.end`, Integer, :to_int};
343
+
344
+ if (from < 0) {
345
+ from += size;
346
+
347
+ if (from < 0) {
348
+ #{raise RangeError, "#{index.inspect} out of range"};
349
+ }
350
+ }
351
+
352
+ if (to < 0) {
353
+ to += size;
354
+ }
355
+
356
+ if (!exclude) {
357
+ to += 1;
358
+ }
359
+
360
+ if (from > size) {
361
+ for (var i = size; i < from; i++) {
362
+ self[i] = nil;
363
+ }
364
+ }
365
+
366
+ if (to < 0) {
367
+ self.splice.apply(self, [from, 0].concat(data));
368
+ }
369
+ else {
370
+ self.splice.apply(self, [from, to - from].concat(data));
371
+ }
372
+
373
+ return value;
374
+ }
375
+ else
376
+ if `extra === undefined`
377
+ length = 1
378
+ else
379
+ length = value
380
+ value = extra
381
+
382
+ if Array === value
383
+ data = value.to_a
384
+ elsif value.respond_to? :to_ary
385
+ data = value.to_ary.to_a
386
+ else
387
+ data = [value]
388
+ end
389
+ end
390
+
391
+ %x{
392
+ var size = self.length,
393
+ index = #{Opal.coerce_to index, Integer, :to_int},
394
+ length = #{Opal.coerce_to length, Integer, :to_int},
395
+ old;
396
+
397
+ if (index < 0) {
398
+ old = index;
399
+ index += size;
400
+
401
+ if (index < 0) {
402
+ #{raise IndexError, "index #{`old`} too small for array; minimum #{`-self.length`}"};
403
+ }
404
+ }
405
+
406
+ if (length < 0) {
407
+ #{raise IndexError, "negative length (#{length})"}
408
+ }
409
+
410
+ if (index > size) {
411
+ for (var i = size; i < index; i++) {
412
+ self[i] = nil;
413
+ }
414
+ }
415
+
416
+ if (extra === undefined) {
417
+ self[index] = value;
418
+ }
419
+ else {
420
+ self.splice.apply(self, [index, length].concat(data));
421
+ }
422
+
423
+ return value;
424
+ }
425
+ end
426
+ end
427
+
428
+ def assoc(object)
429
+ %x{
430
+ for (var i = 0, length = self.length, item; i < length; i++) {
431
+ if (item = self[i], item.length && #{`item[0]` == object}) {
432
+ return item;
433
+ }
434
+ }
435
+
436
+ return nil;
437
+ }
438
+ end
439
+
440
+ def at(index)
441
+ index = Opal.coerce_to index, Integer, :to_int
442
+
443
+ %x{
444
+ if (index < 0) {
445
+ index += self.length;
446
+ }
447
+
448
+ if (index < 0 || index >= self.length) {
449
+ return nil;
450
+ }
451
+
452
+ return self[index];
453
+ }
454
+ end
455
+
456
+ def cycle(n = nil, &block)
457
+ return if empty? || n == 0
458
+
459
+ return enum_for :cycle, n unless block
460
+
461
+ if n.nil?
462
+ %x{
463
+ while (true) {
464
+ for (var i = 0, length = self.length; i < length; i++) {
465
+ var value = $opal.$yield1(block, self[i]);
466
+
467
+ if (value === $breaker) {
468
+ return $breaker.$v;
469
+ }
470
+ }
471
+ }
472
+ }
473
+ else
474
+ n = Opal.coerce_to! n, Integer, :to_int
475
+
476
+ %x{
477
+ if (n <= 0) {
478
+ return self;
479
+ }
480
+
481
+ while (n > 0) {
482
+ for (var i = 0, length = self.length; i < length; i++) {
483
+ var value = $opal.$yield1(block, self[i]);
484
+
485
+ if (value === $breaker) {
486
+ return $breaker.$v;
487
+ }
488
+ }
489
+
490
+ n--;
491
+ }
492
+ }
493
+ end
494
+
495
+ self
496
+ end
497
+
498
+ def clear
499
+ `self.splice(0, self.length)`
500
+
501
+ self
502
+ end
503
+
504
+ def clone
505
+ copy = []
506
+ copy.initialize_clone(self)
507
+ copy
508
+ end
509
+
510
+ def dup
511
+ copy = []
512
+ copy.initialize_dup(self)
513
+ copy
514
+ end
515
+
516
+ def initialize_copy(other)
517
+ replace other
518
+ end
519
+
520
+ def collect(&block)
521
+ return enum_for :collect unless block_given?
522
+
523
+ %x{
524
+ var result = [];
525
+
526
+ for (var i = 0, length = self.length; i < length; i++) {
527
+ var value = Opal.$yield1(block, self[i]);
528
+
529
+ if (value === $breaker) {
530
+ return $breaker.$v;
531
+ }
532
+
533
+ result.push(value);
534
+ }
535
+
536
+ return result;
537
+ }
538
+ end
539
+
540
+ def collect!(&block)
541
+ return enum_for :collect! unless block_given?
542
+
543
+ %x{
544
+ for (var i = 0, length = self.length; i < length; i++) {
545
+ var value = Opal.$yield1(block, self[i]);
546
+
547
+ if (value === $breaker) {
548
+ return $breaker.$v;
549
+ }
550
+
551
+ self[i] = value;
552
+ }
553
+ }
554
+
555
+ self
556
+ end
557
+
558
+ def compact
559
+ %x{
560
+ var result = [];
561
+
562
+ for (var i = 0, length = self.length, item; i < length; i++) {
563
+ if ((item = self[i]) !== nil) {
564
+ result.push(item);
565
+ }
566
+ }
567
+
568
+ return result;
569
+ }
570
+ end
571
+
572
+ def compact!
573
+ %x{
574
+ var original = self.length;
575
+
576
+ for (var i = 0, length = self.length; i < length; i++) {
577
+ if (self[i] === nil) {
578
+ self.splice(i, 1);
579
+
580
+ length--;
581
+ i--;
582
+ }
583
+ }
584
+
585
+ return self.length === original ? nil : self;
586
+ }
587
+ end
588
+
589
+ def concat(other)
590
+ if Array === other
591
+ other = other.to_a
592
+ else
593
+ other = Opal.coerce_to(other, Array, :to_ary).to_a
594
+ end
595
+
596
+ %x{
597
+ for (var i = 0, length = other.length; i < length; i++) {
598
+ self.push(other[i]);
599
+ }
600
+ }
601
+
602
+ self
603
+ end
604
+
605
+ def delete(object)
606
+ %x{
607
+ var original = self.length;
608
+
609
+ for (var i = 0, length = original; i < length; i++) {
610
+ if (#{`self[i]` == object}) {
611
+ self.splice(i, 1);
612
+
613
+ length--;
614
+ i--;
615
+ }
616
+ }
617
+
618
+ return self.length === original ? nil : object;
619
+ }
620
+ end
621
+
622
+ def delete_at(index)
623
+ %x{
624
+ index = #{Opal.coerce_to `index`, Integer, :to_int};
625
+
626
+ if (index < 0) {
627
+ index += self.length;
628
+ }
629
+
630
+ if (index < 0 || index >= self.length) {
631
+ return nil;
632
+ }
633
+
634
+ var result = self[index];
635
+
636
+ self.splice(index, 1);
637
+
638
+ return result;
639
+ }
640
+ end
641
+
642
+ def delete_if(&block)
643
+ return enum_for :delete_if unless block_given?
644
+
645
+ %x{
646
+ for (var i = 0, length = self.length, value; i < length; i++) {
647
+ if ((value = block(self[i])) === $breaker) {
648
+ return $breaker.$v;
649
+ }
650
+
651
+ if (value !== false && value !== nil) {
652
+ self.splice(i, 1);
653
+
654
+ length--;
655
+ i--;
656
+ }
657
+ }
658
+ }
659
+
660
+ self
661
+ end
662
+
663
+ def drop(number)
664
+ %x{
665
+ if (number < 0) {
666
+ #{raise ArgumentError}
667
+ }
668
+
669
+ return self.slice(number);
670
+ }
671
+ end
672
+
673
+ alias dup clone
674
+
675
+ def each(&block)
676
+ return enum_for :each unless block_given?
677
+
678
+ %x{
679
+ for (var i = 0, length = self.length; i < length; i++) {
680
+ var value = $opal.$yield1(block, self[i]);
681
+
682
+ if (value == $breaker) {
683
+ return $breaker.$v;
684
+ }
685
+ }
686
+ }
687
+
688
+ self
689
+ end
690
+
691
+ def each_index(&block)
692
+ return enum_for :each_index unless block_given?
693
+
694
+ %x{
695
+ for (var i = 0, length = self.length; i < length; i++) {
696
+ var value = $opal.$yield1(block, i);
697
+
698
+ if (value === $breaker) {
699
+ return $breaker.$v;
700
+ }
701
+ }
702
+ }
703
+
704
+ self
705
+ end
706
+
707
+ def empty?
708
+ `self.length === 0`
709
+ end
710
+
711
+ def eql?(other)
712
+ return true if `self === other`
713
+ return false unless Array === other
714
+
715
+ other = other.to_a
716
+
717
+ return false unless `self.length === other.length`
718
+
719
+ %x{
720
+ for (var i = 0, length = self.length; i < length; i++) {
721
+ var a = self[i],
722
+ b = other[i];
723
+
724
+ if (a.$$is_array && b.$$is_array && (a === self)) {
725
+ continue;
726
+ }
727
+
728
+ if (!#{`a`.eql? `b`}) {
729
+ return false;
730
+ }
731
+ }
732
+ }
733
+
734
+ true
735
+ end
736
+
737
+ def fetch(index, defaults = undefined, &block)
738
+ %x{
739
+ var original = index;
740
+
741
+ index = #{Opal.coerce_to `index`, Integer, :to_int};
742
+
743
+ if (index < 0) {
744
+ index += self.length;
745
+ }
746
+
747
+ if (index >= 0 && index < self.length) {
748
+ return self[index];
749
+ }
750
+
751
+ if (block !== nil) {
752
+ return block(original);
753
+ }
754
+
755
+ if (defaults != null) {
756
+ return defaults;
757
+ }
758
+
759
+ if (self.length === 0) {
760
+ #{raise IndexError, "index #{`original`} outside of array bounds: 0...0"}
761
+ }
762
+ else {
763
+ #{raise IndexError, "index #{`original`} outside of array bounds: -#{`self.length`}...#{`self.length`}"};
764
+ }
765
+ }
766
+ end
767
+
768
+ def fill(*args, &block)
769
+ if block
770
+ if `args.length > 2`
771
+ raise ArgumentError, "wrong number of arguments (#{args.length} for 0..2)"
772
+ end
773
+
774
+ one, two = args
775
+ else
776
+ if `args.length == 0`
777
+ raise ArgumentError, "wrong number of arguments (0 for 1..3)"
778
+ elsif `args.length > 3`
779
+ raise ArgumentError, "wrong number of arguments (#{args.length} for 1..3)"
780
+ end
781
+
782
+ obj, one, two = args
783
+ end
784
+
785
+ if Range === one
786
+ raise TypeError, "length invalid with range" if two
787
+
788
+ left = Opal.coerce_to one.begin, Integer, :to_int
789
+ `left += #@length` if `left < 0`
790
+ raise RangeError, "#{one.inspect} out of range" if `left < 0`
791
+
792
+ right = Opal.coerce_to one.end, Integer, :to_int
793
+ `right += #@length` if `right < 0`
794
+ `right += 1` unless one.exclude_end?
795
+
796
+ return self if `right <= left`
797
+ elsif one
798
+ left = Opal.coerce_to one, Integer, :to_int
799
+ `left += #@length` if `left < 0`
800
+ left = 0 if `left < 0`
801
+
802
+ if two
803
+ right = Opal.coerce_to two, Integer, :to_int
804
+
805
+ return self if `right == 0`
806
+
807
+ `right += left`
808
+ else
809
+ right = @length
810
+ end
811
+ else
812
+ left = 0
813
+ right = @length
814
+ end
815
+
816
+ if `left > #@length`
817
+ %x{
818
+ for (var i = #@length; i < right; i++) {
819
+ self[i] = nil;
820
+ }
821
+ }
822
+ end
823
+
824
+ if `right > #@length`
825
+ @length = right
826
+ end
827
+
828
+ if block
829
+ %x{
830
+ for (var length = #@length; left < right; left++) {
831
+ var value = block(left);
832
+
833
+ if (value === $breaker) {
834
+ return $breaker.$v;
835
+ }
836
+
837
+ self[left] = value;
838
+ }
839
+ }
840
+ else
841
+ %x{
842
+ for (var length = #@length; left < right; left++) {
843
+ self[left] = #{obj};
844
+ }
845
+ }
846
+ end
847
+
848
+ self
849
+ end
850
+
851
+ def first(count = undefined)
852
+ %x{
853
+ if (count == null) {
854
+ return self.length === 0 ? nil : self[0];
855
+ }
856
+
857
+ count = #{Opal.coerce_to `count`, Integer, :to_int};
858
+
859
+ if (count < 0) {
860
+ #{raise ArgumentError, 'negative array size'};
861
+ }
862
+
863
+ return self.slice(0, count);
864
+ }
865
+ end
866
+
867
+ def flatten(level = undefined)
868
+ %x{
869
+ var result = [];
870
+
871
+ for (var i = 0, length = self.length; i < length; i++) {
872
+ var item = self[i];
873
+
874
+ if (#{Opal.respond_to? `item`, :to_ary}) {
875
+ item = #{`item`.to_ary};
876
+
877
+ if (level == null) {
878
+ result.push.apply(result, #{`item`.flatten.to_a});
879
+ }
880
+ else if (level == 0) {
881
+ result.push(item);
882
+ }
883
+ else {
884
+ result.push.apply(result, #{`item`.flatten(`level - 1`).to_a});
885
+ }
886
+ }
887
+ else {
888
+ result.push(item);
889
+ }
890
+ }
891
+
892
+ return result;
893
+ }
894
+ end
895
+
896
+ def flatten!(level = undefined)
897
+ %x{
898
+ var flattened = #{flatten level};
899
+
900
+ if (self.length == flattened.length) {
901
+ for (var i = 0, length = self.length; i < length; i++) {
902
+ if (self[i] !== flattened[i]) {
903
+ break;
904
+ }
905
+ }
906
+
907
+ if (i == length) {
908
+ return nil;
909
+ }
910
+ }
911
+
912
+ #{replace `flattened`};
913
+ }
914
+
915
+ self
916
+ end
917
+
918
+ def hash
919
+ `self.$$id || (self.$$id = Opal.uid())`
920
+ end
921
+
922
+ def include?(member)
923
+ %x{
924
+ for (var i = 0, length = self.length; i < length; i++) {
925
+ if (#{`self[i]` == member}) {
926
+ return true;
927
+ }
928
+ }
929
+
930
+ return false;
931
+ }
932
+ end
933
+
934
+ def index(object=undefined, &block)
935
+ %x{
936
+ if (object != null) {
937
+ for (var i = 0, length = self.length; i < length; i++) {
938
+ if (#{`self[i]` == object}) {
939
+ return i;
940
+ }
941
+ }
942
+ }
943
+ else if (block !== nil) {
944
+ for (var i = 0, length = self.length, value; i < length; i++) {
945
+ if ((value = block(self[i])) === $breaker) {
946
+ return $breaker.$v;
947
+ }
948
+
949
+ if (value !== false && value !== nil) {
950
+ return i;
951
+ }
952
+ }
953
+ }
954
+ else {
955
+ return #{enum_for :index};
956
+ }
957
+
958
+ return nil;
959
+ }
960
+ end
961
+
962
+ def insert(index, *objects)
963
+ %x{
964
+ index = #{Opal.coerce_to `index`, Integer, :to_int};
965
+
966
+ if (objects.length > 0) {
967
+ if (index < 0) {
968
+ index += self.length + 1;
969
+
970
+ if (index < 0) {
971
+ #{ raise IndexError, "#{index} is out of bounds" };
972
+ }
973
+ }
974
+ if (index > self.length) {
975
+ for (var i = self.length; i < index; i++) {
976
+ self.push(nil);
977
+ }
978
+ }
979
+
980
+ self.splice.apply(self, [index, 0].concat(objects));
981
+ }
982
+ }
983
+
984
+ self
985
+ end
986
+
987
+ def inspect
988
+ %x{
989
+ var i, inspect, el, el_insp, length, object_id;
990
+
991
+ inspect = [];
992
+ object_id = #{object_id};
993
+ length = self.length;
994
+
995
+ for (i = 0; i < length; i++) {
996
+ el = #{self[`i`]};
997
+
998
+ // Check object_id to ensure it's not the same array get into an infinite loop
999
+ el_insp = #{`el`.object_id} === object_id ? '[...]' : #{`el`.inspect};
1000
+
1001
+ inspect.push(el_insp);
1002
+ }
1003
+ return '[' + inspect.join(', ') + ']';
1004
+ }
1005
+ end
1006
+
1007
+ def join(sep = nil)
1008
+ return "" if `self.length === 0`
1009
+
1010
+ if `sep === nil`
1011
+ sep = $,
1012
+ end
1013
+
1014
+ %x{
1015
+ var result = [];
1016
+
1017
+ for (var i = 0, length = self.length; i < length; i++) {
1018
+ var item = self[i];
1019
+
1020
+ if (#{Opal.respond_to? `item`, :to_str}) {
1021
+ var tmp = #{`item`.to_str};
1022
+
1023
+ if (tmp !== nil) {
1024
+ result.push(#{`tmp`.to_s});
1025
+
1026
+ continue;
1027
+ }
1028
+ }
1029
+
1030
+ if (#{Opal.respond_to? `item`, :to_ary}) {
1031
+ var tmp = #{`item`.to_ary};
1032
+
1033
+ if (tmp !== nil) {
1034
+ result.push(#{`tmp`.join(sep)});
1035
+
1036
+ continue;
1037
+ }
1038
+ }
1039
+
1040
+ if (#{Opal.respond_to? `item`, :to_s}) {
1041
+ var tmp = #{`item`.to_s};
1042
+
1043
+ if (tmp !== nil) {
1044
+ result.push(tmp);
1045
+
1046
+ continue;
1047
+ }
1048
+ }
1049
+
1050
+ #{raise NoMethodError, "#{Opal.inspect(`item`)} doesn't respond to #to_str, #to_ary or #to_s"};
1051
+ }
1052
+
1053
+ if (sep === nil) {
1054
+ return result.join('');
1055
+ }
1056
+ else {
1057
+ return result.join(#{Opal.coerce_to!(sep, String, :to_str).to_s});
1058
+ }
1059
+ }
1060
+ end
1061
+
1062
+ def keep_if(&block)
1063
+ return enum_for :keep_if unless block_given?
1064
+
1065
+ %x{
1066
+ for (var i = 0, length = self.length, value; i < length; i++) {
1067
+ if ((value = block(self[i])) === $breaker) {
1068
+ return $breaker.$v;
1069
+ }
1070
+
1071
+ if (value === false || value === nil) {
1072
+ self.splice(i, 1);
1073
+
1074
+ length--;
1075
+ i--;
1076
+ }
1077
+ }
1078
+ }
1079
+
1080
+ self
1081
+ end
1082
+
1083
+ def last(count = undefined)
1084
+ %x{
1085
+ if (count == null) {
1086
+ return self.length === 0 ? nil : self[self.length - 1];
1087
+ }
1088
+
1089
+ count = #{Opal.coerce_to `count`, Integer, :to_int};
1090
+
1091
+ if (count < 0) {
1092
+ #{raise ArgumentError, 'negative array size'};
1093
+ }
1094
+
1095
+ if (count > self.length) {
1096
+ count = self.length;
1097
+ }
1098
+
1099
+ return self.slice(self.length - count, self.length);
1100
+ }
1101
+ end
1102
+
1103
+ def length
1104
+ `self.length`
1105
+ end
1106
+
1107
+ alias map collect
1108
+
1109
+ alias map! collect!
1110
+
1111
+ def pop(count = undefined)
1112
+ if `count === undefined`
1113
+ return if `self.length === 0`
1114
+ return `self.pop()`
1115
+ end
1116
+
1117
+ count = Opal.coerce_to count, Integer, :to_int
1118
+
1119
+ if `count < 0`
1120
+ raise ArgumentError, 'negative array size'
1121
+ end
1122
+
1123
+ return [] if `self.length === 0`
1124
+
1125
+ if `count > self.length`
1126
+ `self.splice(0, self.length)`
1127
+ else
1128
+ `self.splice(self.length - count, self.length)`
1129
+ end
1130
+ end
1131
+
1132
+ def push(*objects)
1133
+ %x{
1134
+ for (var i = 0, length = objects.length; i < length; i++) {
1135
+ self.push(objects[i]);
1136
+ }
1137
+ }
1138
+
1139
+ self
1140
+ end
1141
+
1142
+ def rassoc(object)
1143
+ %x{
1144
+ for (var i = 0, length = self.length, item; i < length; i++) {
1145
+ item = self[i];
1146
+
1147
+ if (item.length && item[1] !== undefined) {
1148
+ if (#{`item[1]` == object}) {
1149
+ return item;
1150
+ }
1151
+ }
1152
+ }
1153
+
1154
+ return nil;
1155
+ }
1156
+ end
1157
+
1158
+ def reject(&block)
1159
+ return enum_for :reject unless block_given?
1160
+
1161
+ %x{
1162
+ var result = [];
1163
+
1164
+ for (var i = 0, length = self.length, value; i < length; i++) {
1165
+ if ((value = block(self[i])) === $breaker) {
1166
+ return $breaker.$v;
1167
+ }
1168
+
1169
+ if (value === false || value === nil) {
1170
+ result.push(self[i]);
1171
+ }
1172
+ }
1173
+ return result;
1174
+ }
1175
+ end
1176
+
1177
+ def reject!(&block)
1178
+ return enum_for :reject! unless block_given?
1179
+
1180
+ original = length
1181
+ delete_if(&block)
1182
+
1183
+ unless length == original
1184
+ self
1185
+ end
1186
+ end
1187
+
1188
+ def replace(other)
1189
+ if Array === other
1190
+ other = other.to_a
1191
+ else
1192
+ other = Opal.coerce_to(other, Array, :to_ary).to_a
1193
+ end
1194
+
1195
+ %x{
1196
+ self.splice(0, self.length);
1197
+ self.push.apply(self, other);
1198
+ }
1199
+
1200
+ self
1201
+ end
1202
+
1203
+ def reverse
1204
+ `self.slice(0).reverse()`
1205
+ end
1206
+
1207
+ def reverse!
1208
+ `self.reverse()`
1209
+ end
1210
+
1211
+ def reverse_each(&block)
1212
+ return enum_for :reverse_each unless block_given?
1213
+
1214
+ reverse.each &block
1215
+ self
1216
+ end
1217
+
1218
+ def rindex(object = undefined, &block)
1219
+ %x{
1220
+ if (object != null) {
1221
+ for (var i = self.length - 1; i >= 0; i--) {
1222
+ if (#{`self[i]` == `object`}) {
1223
+ return i;
1224
+ }
1225
+ }
1226
+ }
1227
+ else if (block !== nil) {
1228
+ for (var i = self.length - 1, value; i >= 0; i--) {
1229
+ if ((value = block(self[i])) === $breaker) {
1230
+ return $breaker.$v;
1231
+ }
1232
+
1233
+ if (value !== false && value !== nil) {
1234
+ return i;
1235
+ }
1236
+ }
1237
+ }
1238
+ else if (object == null) {
1239
+ return #{enum_for :rindex};
1240
+ }
1241
+
1242
+ return nil;
1243
+ }
1244
+ end
1245
+
1246
+ def sample(n = nil)
1247
+ return nil if !n && empty?
1248
+ return [] if n && empty?
1249
+
1250
+ if n
1251
+ (1 .. n).map {
1252
+ self[rand(length)]
1253
+ }
1254
+ else
1255
+ self[rand(length)]
1256
+ end
1257
+ end
1258
+
1259
+ def select(&block)
1260
+ return enum_for :select unless block_given?
1261
+
1262
+ %x{
1263
+ var result = [];
1264
+
1265
+ for (var i = 0, length = self.length, item, value; i < length; i++) {
1266
+ item = self[i];
1267
+
1268
+ if ((value = $opal.$yield1(block, item)) === $breaker) {
1269
+ return $breaker.$v;
1270
+ }
1271
+
1272
+ if (value !== false && value !== nil) {
1273
+ result.push(item);
1274
+ }
1275
+ }
1276
+
1277
+ return result;
1278
+ }
1279
+ end
1280
+
1281
+ def select!(&block)
1282
+ return enum_for :select! unless block_given?
1283
+
1284
+ %x{
1285
+ var original = self.length;
1286
+ #{ keep_if &block };
1287
+ return self.length === original ? nil : self;
1288
+ }
1289
+ end
1290
+
1291
+ def shift(count = undefined)
1292
+ if `count === undefined`
1293
+ return if `self.length === 0`
1294
+ return `self.shift()`
1295
+ end
1296
+
1297
+ count = Opal.coerce_to count, Integer, :to_int
1298
+
1299
+ if `count < 0`
1300
+ raise ArgumentError, 'negative array size'
1301
+ end
1302
+
1303
+ return [] if `self.length === 0`
1304
+
1305
+ `self.splice(0, count)`
1306
+ end
1307
+
1308
+ alias size length
1309
+
1310
+ def shuffle
1311
+ clone.shuffle!
1312
+ end
1313
+
1314
+ def shuffle!
1315
+ %x{
1316
+ for (var i = self.length - 1; i > 0; i--) {
1317
+ var tmp = self[i],
1318
+ j = Math.floor(Math.random() * (i + 1));
1319
+
1320
+ self[i] = self[j];
1321
+ self[j] = tmp;
1322
+ }
1323
+ }
1324
+
1325
+ self
1326
+ end
1327
+
1328
+ alias slice []
1329
+
1330
+ def slice!(index, length = undefined)
1331
+ %x{
1332
+ if (index < 0) {
1333
+ index += self.length;
1334
+ }
1335
+
1336
+ if (length != null) {
1337
+ return self.splice(index, length);
1338
+ }
1339
+
1340
+ if (index < 0 || index >= self.length) {
1341
+ return nil;
1342
+ }
1343
+
1344
+ return self.splice(index, 1)[0];
1345
+ }
1346
+ end
1347
+
1348
+ def sort(&block)
1349
+ return self unless `self.length > 1`
1350
+
1351
+ %x{
1352
+ if (!#{block_given?}) {
1353
+ block = function(a, b) {
1354
+ return #{`a` <=> `b`};
1355
+ };
1356
+ }
1357
+
1358
+ try {
1359
+ return self.slice().sort(function(x, y) {
1360
+ var ret = block(x, y);
1361
+
1362
+ if (ret === $breaker) {
1363
+ throw $breaker;
1364
+ }
1365
+ else if (ret === nil) {
1366
+ #{raise ArgumentError, "comparison of #{`x`.inspect} with #{`y`.inspect} failed"};
1367
+ }
1368
+
1369
+ return #{`ret` > 0} ? 1 : (#{`ret` < 0} ? -1 : 0);
1370
+ });
1371
+ }
1372
+ catch (e) {
1373
+ if (e === $breaker) {
1374
+ return $breaker.$v;
1375
+ }
1376
+ else {
1377
+ throw e;
1378
+ }
1379
+ }
1380
+ }
1381
+ end
1382
+
1383
+ def sort!(&block)
1384
+ %x{
1385
+ var result;
1386
+
1387
+ if (#{block_given?}) {
1388
+ result = #{`self.slice()`.sort(&block)};
1389
+ }
1390
+ else {
1391
+ result = #{`self.slice()`.sort};
1392
+ }
1393
+
1394
+ self.length = 0;
1395
+ for(var i = 0, length = result.length; i < length; i++) {
1396
+ self.push(result[i]);
1397
+ }
1398
+
1399
+ return self;
1400
+ }
1401
+ end
1402
+
1403
+ def take(count)
1404
+ %x{
1405
+ if (count < 0) {
1406
+ #{raise ArgumentError};
1407
+ }
1408
+
1409
+ return self.slice(0, count);
1410
+ }
1411
+ end
1412
+
1413
+ def take_while(&block)
1414
+ %x{
1415
+ var result = [];
1416
+
1417
+ for (var i = 0, length = self.length, item, value; i < length; i++) {
1418
+ item = self[i];
1419
+
1420
+ if ((value = block(item)) === $breaker) {
1421
+ return $breaker.$v;
1422
+ }
1423
+
1424
+ if (value === false || value === nil) {
1425
+ return result;
1426
+ }
1427
+
1428
+ result.push(item);
1429
+ }
1430
+
1431
+ return result;
1432
+ }
1433
+ end
1434
+
1435
+ def to_a
1436
+ self
1437
+ end
1438
+
1439
+ alias to_ary to_a
1440
+
1441
+ alias to_s inspect
1442
+
1443
+ def transpose
1444
+ return [] if empty?
1445
+
1446
+ result = []
1447
+ max = nil
1448
+
1449
+ each {|row|
1450
+ if Array === row
1451
+ row = row.to_a
1452
+ else
1453
+ row = Opal.coerce_to(row, Array, :to_ary).to_a
1454
+ end
1455
+
1456
+ max ||= `row.length`
1457
+
1458
+ if `row.length` != max
1459
+ raise IndexError, "element size differs (#{`row.length`} should be #{max}"
1460
+ end
1461
+
1462
+ `row.length`.times {|i|
1463
+ entry = (result[i] ||= [])
1464
+ entry << row.at(i)
1465
+ }
1466
+ }
1467
+
1468
+ result
1469
+ end
1470
+
1471
+ def uniq
1472
+ %x{
1473
+ var result = [],
1474
+ seen = {};
1475
+
1476
+ for (var i = 0, length = self.length, item, hash; i < length; i++) {
1477
+ item = self[i];
1478
+ hash = item;
1479
+
1480
+ if (!seen[hash]) {
1481
+ seen[hash] = true;
1482
+
1483
+ result.push(item);
1484
+ }
1485
+ }
1486
+
1487
+ return result;
1488
+ }
1489
+ end
1490
+
1491
+ def uniq!
1492
+ %x{
1493
+ var original = self.length,
1494
+ seen = {};
1495
+
1496
+ for (var i = 0, length = original, item, hash; i < length; i++) {
1497
+ item = self[i];
1498
+ hash = item;
1499
+
1500
+ if (!seen[hash]) {
1501
+ seen[hash] = true;
1502
+ }
1503
+ else {
1504
+ self.splice(i, 1);
1505
+
1506
+ length--;
1507
+ i--;
1508
+ }
1509
+ }
1510
+
1511
+ return self.length === original ? nil : self;
1512
+ }
1513
+ end
1514
+
1515
+ def unshift(*objects)
1516
+ %x{
1517
+ for (var i = objects.length - 1; i >= 0; i--) {
1518
+ self.unshift(objects[i]);
1519
+ }
1520
+ }
1521
+
1522
+ self
1523
+ end
1524
+
1525
+ def zip(*others, &block)
1526
+ %x{
1527
+ var result = [], size = self.length, part, o;
1528
+
1529
+ for (var i = 0; i < size; i++) {
1530
+ part = [self[i]];
1531
+
1532
+ for (var j = 0, jj = others.length; j < jj; j++) {
1533
+ o = others[j][i];
1534
+
1535
+ if (o == null) {
1536
+ o = nil;
1537
+ }
1538
+
1539
+ part[j + 1] = o;
1540
+ }
1541
+
1542
+ result[i] = part;
1543
+ }
1544
+
1545
+ if (block !== nil) {
1546
+ for (var i = 0; i < size; i++) {
1547
+ block(result[i]);
1548
+ }
1549
+
1550
+ return nil;
1551
+ }
1552
+
1553
+ return result;
1554
+ }
1555
+ end
1556
+ end