opal 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (325) hide show
  1. data/.gitignore +5 -10
  2. data/LICENSE +75 -0
  3. data/README.md +55 -3
  4. data/Rakefile +62 -139
  5. data/bin/opal +7 -10
  6. data/gems/core/README.md +5 -0
  7. data/gems/core/Rakefile +7 -0
  8. data/gems/core/core.gemspec +13 -0
  9. data/gems/core/lib/core.rb +33 -0
  10. data/gems/core/lib/core/array.rb +1470 -0
  11. data/gems/core/lib/core/basic_object.rb +15 -0
  12. data/gems/core/lib/core/class.rb +31 -0
  13. data/gems/core/lib/core/dir.rb +26 -0
  14. data/gems/core/lib/core/error.rb +43 -0
  15. data/gems/core/lib/core/false_class.rb +21 -0
  16. data/gems/core/lib/core/file.rb +54 -0
  17. data/gems/core/lib/core/hash.rb +725 -0
  18. data/gems/core/lib/core/kernel.rb +240 -0
  19. data/gems/core/lib/core/module.rb +98 -0
  20. data/gems/core/lib/core/nil_class.rb +41 -0
  21. data/gems/core/lib/core/numeric.rb +370 -0
  22. data/gems/core/lib/core/proc.rb +11 -0
  23. data/gems/core/lib/core/range.rb +17 -0
  24. data/gems/core/lib/core/regexp.rb +18 -0
  25. data/gems/core/lib/core/string.rb +328 -0
  26. data/gems/core/lib/core/symbol.rb +15 -0
  27. data/gems/core/lib/core/top_self.rb +8 -0
  28. data/gems/core/lib/core/true_class.rb +20 -0
  29. data/gems/core/lib/core/vm.rb +16 -0
  30. data/{opals/opal/opal → gems/core}/spec/core/array/append_spec.rb +0 -0
  31. data/{opals/opal/opal → gems/core}/spec/core/array/assoc_spec.rb +0 -0
  32. data/{opals/opal/opal → gems/core}/spec/core/array/at_spec.rb +0 -0
  33. data/{opals/opal/opal → gems/core}/spec/core/array/clear_spec.rb +1 -1
  34. data/{opals/opal/opal → gems/core}/spec/core/array/collect_bang_spec.rb +0 -0
  35. data/{opals/opal/opal → gems/core}/spec/core/array/collect_spec.rb +0 -0
  36. data/gems/core/spec/core/array/compact_spec.rb +41 -0
  37. data/{opals/opal/opal → gems/core}/spec/core/array/concat_spec.rb +0 -0
  38. data/{opals/opal/opal → gems/core}/spec/core/array/constructor_spec.rb +0 -0
  39. data/{opals/opal/opal → gems/core}/spec/core/array/each_spec.rb +0 -0
  40. data/{opals/opal/opal → gems/core}/spec/core/array/element_reference_spec.rb +0 -0
  41. data/{opals/opal/opal → gems/core}/spec/core/array/first_spec.rb +1 -1
  42. data/{opals/opal/opal → gems/core}/spec/core/array/include_spec.rb +0 -0
  43. data/gems/core/spec/core/array/join_spec.rb +6 -0
  44. data/gems/core/spec/core/array/last_spec.rb +51 -0
  45. data/gems/core/spec/core/array/length_spec.rb +6 -0
  46. data/{opals/opal/opal → gems/core}/spec/core/array/map_spec.rb +2 -0
  47. data/gems/core/spec/core/array/reverse_spec.rb +6 -0
  48. data/{opals/opal/opal → gems/core}/spec/core/builtin_constants/builtin_constants_spec.rb +0 -0
  49. data/{opals/opal/opal → gems/core}/spec/core/false/and_spec.rb +0 -0
  50. data/{opals/opal/opal → gems/core}/spec/core/false/inspect_spec.rb +0 -0
  51. data/{opals/opal/opal → gems/core}/spec/core/false/or_spec.rb +0 -0
  52. data/{opals/opal/opal → gems/core}/spec/core/false/to_s_spec.rb +0 -0
  53. data/{opals/opal/opal → gems/core}/spec/core/false/xor_spec.rb +0 -0
  54. data/{opals/opal/opal → gems/core}/spec/core/file/join_spec.rb +1 -1
  55. data/gems/core/spec/core/hash/assoc_spec.rb +32 -0
  56. data/{opals/opal/opal → gems/core}/spec/core/kernel/instance_eval_spec.rb +0 -0
  57. data/{opals/opal/opal → gems/core}/spec/core/kernel/loop_spec.rb +0 -0
  58. data/{opals/opal/opal → gems/core}/spec/core/kernel/raise_spec.rb +0 -0
  59. data/{opals/opal/opal → gems/core}/spec/core/module/attr_accessor_spec.rb +0 -0
  60. data/{opals/opal/opal → gems/core}/spec/core/number/lt_spec.rb +0 -0
  61. data/gems/core/spec/core/string/sub_spec.rb +24 -0
  62. data/{opals/opal/opal → gems/core}/spec/core/true/and_spec.rb +0 -0
  63. data/{opals/opal/opal → gems/core}/spec/core/true/inspect_spec.rb +0 -0
  64. data/{opals/opal/opal → gems/core}/spec/core/true/or_spec.rb +0 -0
  65. data/{opals/opal/opal → gems/core}/spec/core/true/to_s_spec.rb +0 -0
  66. data/{opals/opal/opal → gems/core}/spec/core/true/xor_spec.rb +0 -0
  67. data/{opals/opal/opal → gems/core}/spec/language/and_spec.rb +2 -3
  68. data/{opals/opal/opal → gems/core}/spec/language/array_spec.rb +21 -5
  69. data/gems/core/spec/language/block_spec.rb +38 -0
  70. data/{opals/opal/opal → gems/core}/spec/language/break_spec.rb +0 -0
  71. data/gems/core/spec/language/case_spec.rb +103 -0
  72. data/{opals/opal/opal → gems/core}/spec/language/def_spec.rb +11 -1
  73. data/{opals/opal/opal → gems/core}/spec/language/eigenclass_spec.rb +0 -0
  74. data/gems/core/spec/language/file_spec.rb +13 -0
  75. data/gems/core/spec/language/fixtures/block.rb +21 -0
  76. data/gems/core/spec/language/fixtures/super.rb +293 -0
  77. data/{opals/opal/opal → gems/core}/spec/language/hash_spec.rb +0 -0
  78. data/{opals/opal/opal → gems/core}/spec/language/if_spec.rb +0 -0
  79. data/{opals/opal/opal → gems/core}/spec/language/loop_spec.rb +0 -0
  80. data/gems/core/spec/language/metaclass_spec.rb +21 -0
  81. data/{opals/opal/opal → gems/core}/spec/language/method_spec.rb +60 -0
  82. data/{opals/opal/opal → gems/core}/spec/language/next_spec.rb +0 -0
  83. data/{opals/opal/opal → gems/core}/spec/language/or_spec.rb +0 -0
  84. data/{opals/opal/opal → gems/core}/spec/language/redo_spec.rb +0 -0
  85. data/gems/core/spec/language/regexp_spec.rb +26 -0
  86. data/{opals/opal/opal → gems/core}/spec/language/rescue_spec.rb +0 -0
  87. data/{opals/opal/opal → gems/core}/spec/language/return_spec.rb +0 -0
  88. data/{opals/opal/opal → gems/core}/spec/language/string_spec.rb +0 -0
  89. data/gems/core/spec/language/super_spec.rb +32 -0
  90. data/{opals/opal/opal → gems/core}/spec/language/until_spec.rb +47 -47
  91. data/gems/core/spec/language/variables_spec.rb +155 -0
  92. data/{opals/opal/opal → gems/core}/spec/language/while_spec.rb +47 -47
  93. data/{opals/opal/opal → gems/core}/spec/spec_helper.rb +1 -1
  94. data/gems/core_fs/README.md +19 -0
  95. data/gems/dev/Rakefile +5 -0
  96. data/gems/dev/lib/dev.js +99 -0
  97. data/gems/dev/lib/dev/generator.js +1264 -0
  98. data/gems/dev/lib/dev/parser.js +979 -0
  99. data/gems/dev/lib/dev/ruby_parser.js +1088 -0
  100. data/gems/dev/lib/dev/ruby_parser.y +1267 -0
  101. data/gems/dev/lib/dev/string_scanner.js +38 -0
  102. data/gems/dev/tools/racc2js/README.md +39 -0
  103. data/gems/dev/tools/racc2js/math_parser.js +222 -0
  104. data/gems/dev/tools/racc2js/math_parser.rb +133 -0
  105. data/gems/dev/tools/racc2js/math_parser.y +28 -0
  106. data/gems/dev/tools/racc2js/parser.js +218 -0
  107. data/gems/dev/tools/racc2js/racc2js.rb +153 -0
  108. data/gems/json/README.md +4 -0
  109. data/gems/json/json.gemspec +14 -0
  110. data/gems/json/lib/json.rb +64 -0
  111. data/gems/json/lib/json/ext.rb +51 -0
  112. data/{opals/opal/browser/lib/browser/json_parse.js → gems/json/lib/json/json2.js} +197 -37
  113. data/gems/ospec/README.md +0 -0
  114. data/gems/ospec/lib/ospec.rb +6 -0
  115. data/gems/ospec/lib/ospec/autorun.rb +3 -0
  116. data/gems/ospec/lib/ospec/dsl.rb +15 -0
  117. data/gems/ospec/lib/ospec/example.rb +11 -0
  118. data/gems/ospec/lib/ospec/example/before_and_after_hooks.rb +56 -0
  119. data/gems/ospec/lib/ospec/example/errors.rb +17 -0
  120. data/gems/ospec/lib/ospec/example/example_group.rb +12 -0
  121. data/gems/ospec/lib/ospec/example/example_group_factory.rb +21 -0
  122. data/gems/ospec/lib/ospec/example/example_group_hierarchy.rb +20 -0
  123. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/example/example_group_methods.rb +26 -68
  124. data/gems/ospec/lib/ospec/example/example_group_proxy.rb +14 -0
  125. data/gems/ospec/lib/ospec/example/example_methods.rb +46 -0
  126. data/gems/ospec/lib/ospec/example/example_proxy.rb +18 -0
  127. data/gems/ospec/lib/ospec/expectations.rb +19 -0
  128. data/gems/ospec/lib/ospec/expectations/errors.rb +8 -0
  129. data/gems/ospec/lib/ospec/expectations/fail_with.rb +8 -0
  130. data/gems/ospec/lib/ospec/expectations/handler.rb +27 -0
  131. data/gems/ospec/lib/ospec/matchers.rb +24 -0
  132. data/{opals/opal/Rakefile → gems/ospec/lib/ospec/matchers/be.rb} +0 -0
  133. data/gems/ospec/lib/ospec/matchers/generated_descriptions.rb +20 -0
  134. data/gems/ospec/lib/ospec/matchers/operator_matcher.rb +52 -0
  135. data/gems/ospec/lib/ospec/runner.rb +40 -0
  136. data/gems/ospec/lib/ospec/runner/example_group_runner.rb +44 -0
  137. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/runner/formatter/html_formatter.rb +31 -40
  138. data/gems/ospec/lib/ospec/runner/formatter/terminal_formatter.rb +48 -0
  139. data/gems/ospec/lib/ospec/runner/options.rb +36 -0
  140. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/runner/reporter.rb +23 -55
  141. data/gems/ospec/ospec.gemspec +0 -0
  142. data/gems/rquery/README.md +9 -0
  143. data/gems/rquery/lib/rquery.rb +10 -0
  144. data/gems/rquery/lib/rquery/ajax.rb +4 -0
  145. data/gems/rquery/lib/rquery/css.rb +96 -0
  146. data/gems/rquery/lib/rquery/document.rb +25 -0
  147. data/gems/rquery/lib/rquery/element.rb +292 -0
  148. data/gems/rquery/lib/rquery/event.rb +108 -0
  149. data/gems/rquery/lib/rquery/jquery.js +8177 -0
  150. data/gems/rquery/lib/rquery/request.rb +138 -0
  151. data/gems/rquery/lib/rquery/response.rb +49 -0
  152. data/gems/rquery/rquery.gemspec +16 -0
  153. data/lib/opal.js +1597 -0
  154. data/lib/opal.rb +6 -69
  155. data/lib/opal/builder.rb +115 -0
  156. data/lib/opal/bundle.rb +131 -0
  157. data/lib/opal/command.rb +11 -0
  158. data/lib/opal/context.rb +69 -0
  159. data/lib/opal/context/console.rb +12 -0
  160. data/lib/opal/context/file_system.rb +19 -0
  161. data/lib/opal/context/loader.rb +117 -0
  162. data/lib/opal/gem.rb +153 -0
  163. data/lib/opal/ruby/nodes.rb +1302 -0
  164. data/lib/opal/ruby/parser.rb +780 -0
  165. data/lib/opal/ruby/ruby_parser.rb +5170 -0
  166. data/lib/opal/ruby/ruby_parser.y +1298 -0
  167. data/opal.gemspec +11 -256
  168. metadata +179 -240
  169. data/.gitmodules +0 -6
  170. data/Opalfile +0 -384
  171. data/VERSION +0 -1
  172. data/demos/apps/browser_demo/index.html +0 -11
  173. data/demos/apps/browser_demo/lib/browser_demo.rb +0 -31
  174. data/demos/apps/simple_opal/Opalfile +0 -13
  175. data/demos/apps/simple_opal/index.html +0 -11
  176. data/demos/apps/simple_opal/lib/app_controller.rb +0 -62
  177. data/demos/apps/simple_opal/lib/main_window.rb +0 -146
  178. data/demos/browser/request/index.html +0 -52
  179. data/demos/browser/request/request.rb +0 -48
  180. data/gen/browser/__PROJECT_NAME__/Rakefile +0 -12
  181. data/gen/browser/__PROJECT_NAME__/index.html +0 -11
  182. data/gen/browser/__PROJECT_NAME__/javascripts/opal.debug.js +0 -4687
  183. data/gen/browser/__PROJECT_NAME__/javascripts/opal.min.js +0 -175
  184. data/gen/browser/__PROJECT_NAME__/lib/__PROJECT_NAME__.rb +0 -1
  185. data/lib/opal/builders/base.rb +0 -50
  186. data/lib/opal/builders/css.rb +0 -46
  187. data/lib/opal/builders/javascript.rb +0 -44
  188. data/lib/opal/builders/opal.rb +0 -79
  189. data/lib/opal/builders/ruby.rb +0 -50
  190. data/lib/opal/builders/ruby/generate.rb +0 -1851
  191. data/lib/opal/builders/ruby/nodes.rb +0 -210
  192. data/lib/opal/builders/ruby/ruby.rb +0 -916
  193. data/lib/opal/builders/ruby/ruby_parser.rb +0 -6008
  194. data/lib/opal/builders/ruby/ruby_parser.rb.y +0 -1451
  195. data/lib/opal/models/build_item.rb +0 -104
  196. data/lib/opal/models/hash_struct.rb +0 -40
  197. data/lib/opal/models/project.rb +0 -252
  198. data/lib/opal/models/struct_accessors.rb +0 -58
  199. data/lib/opal/models/target.rb +0 -176
  200. data/lib/opal/opal/build.rb +0 -169
  201. data/lib/opal/opal/env/console.rb +0 -66
  202. data/lib/opal/opal/env/fs.rb +0 -98
  203. data/lib/opal/opal/env/object.rb +0 -48
  204. data/lib/opal/opal/environment.rb +0 -139
  205. data/lib/opal/opal/gen.rb +0 -62
  206. data/lib/opal/opal/opal.rb +0 -75
  207. data/lib/opal/opal/repl.rb +0 -38
  208. data/lib/opal/opalfile/dsl.rb +0 -62
  209. data/lib/opal/opalfile/opalfile.rb +0 -133
  210. data/lib/opal/opalfile/task.rb +0 -96
  211. data/lib/opal/opalfile/task_manager.rb +0 -63
  212. data/lib/opal/opalfile/task_scope.rb +0 -52
  213. data/lib/opal/rack/app_server.rb +0 -119
  214. data/lib/opal/rake/opal_task.rb +0 -34
  215. data/opals/opal/README.md +0 -37
  216. data/opals/opal/browser/Opalfile +0 -11
  217. data/opals/opal/browser/README.md +0 -146
  218. data/opals/opal/browser/SIZZLE_LICESNSE.txt +0 -148
  219. data/opals/opal/browser/lib/browser.rb +0 -118
  220. data/opals/opal/browser/lib/browser/builder.rb +0 -41
  221. data/opals/opal/browser/lib/browser/canvas_context.rb +0 -115
  222. data/opals/opal/browser/lib/browser/dimensions.rb +0 -50
  223. data/opals/opal/browser/lib/browser/document.rb +0 -146
  224. data/opals/opal/browser/lib/browser/element.rb +0 -487
  225. data/opals/opal/browser/lib/browser/element/attributes.rb +0 -88
  226. data/opals/opal/browser/lib/browser/element/css.rb +0 -290
  227. data/opals/opal/browser/lib/browser/element/form.rb +0 -146
  228. data/opals/opal/browser/lib/browser/event/dom_events.rb +0 -81
  229. data/opals/opal/browser/lib/browser/event/event.rb +0 -177
  230. data/opals/opal/browser/lib/browser/event/trigger_events.rb +0 -53
  231. data/opals/opal/browser/lib/browser/geometry.rb +0 -97
  232. data/opals/opal/browser/lib/browser/json.rb +0 -32
  233. data/opals/opal/browser/lib/browser/request/request.rb +0 -201
  234. data/opals/opal/browser/lib/browser/sizzle.js +0 -1068
  235. data/opals/opal/browser/lib/browser/string.rb +0 -42
  236. data/opals/opal/browser/lib/browser/touch.rb +0 -37
  237. data/opals/opal/browser/lib/browser/vml_context.js +0 -33
  238. data/opals/opal/browser/lib/browser/window.rb +0 -36
  239. data/opals/opal/browser/spec/browser/browser_detection_spec.rb +0 -7
  240. data/opals/opal/browser/spec/document/aref_spec.rb +0 -110
  241. data/opals/opal/browser/spec/document/ready_spec.rb +0 -16
  242. data/opals/opal/browser/spec/element/body_spec.rb +0 -11
  243. data/opals/opal/browser/spec/element/clear_spec.rb +0 -26
  244. data/opals/opal/browser/spec/element/empty_spec.rb +0 -29
  245. data/opals/opal/browser/spec/element/has_class_spec.rb +0 -40
  246. data/opals/opal/browser/spec/element/hidden_spec.rb +0 -23
  247. data/opals/opal/browser/spec/element/hide_spec.rb +0 -31
  248. data/opals/opal/browser/spec/element/remove_spec.rb +0 -25
  249. data/opals/opal/browser/spec/element/show_spec.rb +0 -31
  250. data/opals/opal/browser/spec/element/style_spec.rb +0 -69
  251. data/opals/opal/browser/spec/element/toggle_spec.rb +0 -31
  252. data/opals/opal/browser/spec/element/visible_spec.rb +0 -23
  253. data/opals/opal/browser/spec/spec_helper.rb +0 -1
  254. data/opals/opal/opal/Opalfile +0 -14
  255. data/opals/opal/opal/spec/core/array/compact_spec.rb +0 -15
  256. data/opals/opal/opal/spec/fixtures/super.rb +0 -70
  257. data/opals/opal/opal/spec/language/____temp_remove_this.rb +0 -12
  258. data/opals/opal/opal/spec/language/block_spec.rb +0 -18
  259. data/opals/opal/opal/spec/language/case_spec.rb +0 -103
  260. data/opals/opal/opal/spec/language/metaclass_spec.rb +0 -21
  261. data/opals/opal/opal/spec/language/super_spec.rb +0 -26
  262. data/opals/opal/runtime/Opalfile +0 -78
  263. data/opals/opal/runtime/README.md +0 -12
  264. data/opals/opal/runtime/docs/debugging.md +0 -51
  265. data/opals/opal/runtime/lib/array.rb +0 -1516
  266. data/opals/opal/runtime/lib/basic_object.rb +0 -49
  267. data/opals/opal/runtime/lib/class.rb +0 -54
  268. data/opals/opal/runtime/lib/dir.rb +0 -36
  269. data/opals/opal/runtime/lib/error.rb +0 -49
  270. data/opals/opal/runtime/lib/false_class.rb +0 -52
  271. data/opals/opal/runtime/lib/file.rb +0 -79
  272. data/opals/opal/runtime/lib/hash.rb +0 -791
  273. data/opals/opal/runtime/lib/io.rb +0 -39
  274. data/opals/opal/runtime/lib/kernel.rb +0 -288
  275. data/opals/opal/runtime/lib/match_data.rb +0 -36
  276. data/opals/opal/runtime/lib/module.rb +0 -109
  277. data/opals/opal/runtime/lib/nil_class.rb +0 -69
  278. data/opals/opal/runtime/lib/number.rb +0 -398
  279. data/opals/opal/runtime/lib/proc.rb +0 -77
  280. data/opals/opal/runtime/lib/range.rb +0 -63
  281. data/opals/opal/runtime/lib/regexp.rb +0 -111
  282. data/opals/opal/runtime/lib/ruby.rb +0 -30
  283. data/opals/opal/runtime/lib/string.rb +0 -328
  284. data/opals/opal/runtime/lib/symbol.rb +0 -40
  285. data/opals/opal/runtime/lib/top_self.rb +0 -33
  286. data/opals/opal/runtime/lib/true_class.rb +0 -45
  287. data/opals/opal/runtime/runtime/browser.js +0 -287
  288. data/opals/opal/runtime/runtime/debug.js +0 -180
  289. data/opals/opal/runtime/runtime/opal.js +0 -1008
  290. data/opals/opal/runtime/runtime/post_opal.js +0 -1
  291. data/opals/opal/runtime/runtime/pre_opal.js +0 -2
  292. data/opals/opal/runtime/runtime/server_side.js +0 -50
  293. data/opals/opal/spec/LICENSE.txt +0 -26
  294. data/opals/opal/spec/Opalfile +0 -5
  295. data/opals/opal/spec/bin/spec.rb +0 -43
  296. data/opals/opal/spec/lib/spec.rb +0 -33
  297. data/opals/opal/spec/lib/spec/dsl.rb +0 -41
  298. data/opals/opal/spec/lib/spec/example.rb +0 -35
  299. data/opals/opal/spec/lib/spec/example/before_and_after_hooks.rb +0 -81
  300. data/opals/opal/spec/lib/spec/example/errors.rb +0 -42
  301. data/opals/opal/spec/lib/spec/example/example_group.rb +0 -37
  302. data/opals/opal/spec/lib/spec/example/example_group_factory.rb +0 -43
  303. data/opals/opal/spec/lib/spec/example/example_group_hierarchy.rb +0 -45
  304. data/opals/opal/spec/lib/spec/example/example_group_proxy.rb +0 -41
  305. data/opals/opal/spec/lib/spec/example/example_methods.rb +0 -73
  306. data/opals/opal/spec/lib/spec/example/example_proxy.rb +0 -48
  307. data/opals/opal/spec/lib/spec/expectations.rb +0 -46
  308. data/opals/opal/spec/lib/spec/expectations/errors.rb +0 -35
  309. data/opals/opal/spec/lib/spec/expectations/fail_with.rb +0 -37
  310. data/opals/opal/spec/lib/spec/expectations/handler.rb +0 -48
  311. data/opals/opal/spec/lib/spec/matchers.rb +0 -50
  312. data/opals/opal/spec/lib/spec/matchers/be.rb +0 -26
  313. data/opals/opal/spec/lib/spec/matchers/generated_descriptions.rb +0 -47
  314. data/opals/opal/spec/lib/spec/matchers/operator_matcher.rb +0 -66
  315. data/opals/opal/spec/lib/spec/runner.rb +0 -48
  316. data/opals/opal/spec/lib/spec/runner/example_group_runner.rb +0 -71
  317. data/opals/opal/spec/lib/spec/runner/formatter/terminal_formatter.rb +0 -82
  318. data/opals/opal/spec/lib/spec/runner/options.rb +0 -63
  319. data/opals/opal/spec/resources/index.html +0 -25
  320. data/opals/opal/spec/resources/spec.css +0 -132
  321. data/spec/cherry_kit/iseq_spec.rb +0 -38
  322. data/spec/spec_helper.rb +0 -16
  323. data/spec/vienna_spec.rb +0 -7
  324. data/yard/index.html +0 -43
  325. data/yard/style.css +0 -765
@@ -0,0 +1,15 @@
1
+ class BasicObject
2
+ def initialize
3
+ # ...
4
+ end
5
+
6
+ def ==(other)
7
+ `if (self == other) return Qtrue;
8
+ return Qfalse;`
9
+ end
10
+
11
+ def equal?(other)
12
+ self == other
13
+ end
14
+ end
15
+
@@ -0,0 +1,31 @@
1
+ class Class
2
+
3
+ # def new(*args)
4
+ # `var obj = self.$m.allocate(self);
5
+ # args.unshift(obj);
6
+
7
+ # obj.$m.initialize.apply(null, args);
8
+
9
+ # return obj;`
10
+ # end
11
+
12
+ # This is what new should be: need to fix compiler for splat args
13
+ #
14
+ # def new(*args)
15
+ # obj = allocate
16
+ # obj.initialize *args
17
+ # obj
18
+ # end
19
+
20
+ def superclass
21
+ `var sup = self.$super;
22
+
23
+ if (!sup) {
24
+ if (self == VM.BasicObject) return nil;
25
+ throw new Error('RuntimeError: uninitialized class');
26
+ }
27
+
28
+ return sup;`
29
+ end
30
+ end
31
+
@@ -0,0 +1,26 @@
1
+
2
+ class Dir
3
+ # OPAL_FS simply points to the main opal.fs namespace. This might be the
4
+ # default fs in the browser, or may be overriden within the opal build tools
5
+ # when running on top of the gem runtime. Both are compatible interfaces.
6
+ `var OPAL_FS = VM.opal.fs;`
7
+
8
+ # Returns a string that is the current working directory for this process.
9
+ #
10
+ # @return [String]
11
+ def self.getwd
12
+ `return OPAL_FS.cwd;`
13
+ end
14
+
15
+ # Returns a string that is the current working directory for this process.
16
+ #
17
+ # @return [String]
18
+ def self.pwd
19
+ `return OPAL_FS.cwd;`
20
+ end
21
+
22
+ def self.[](*a)
23
+ `return OPAL_FS.glob.apply(OPAL_FS, a);`
24
+ end
25
+ end
26
+
@@ -0,0 +1,43 @@
1
+ class Exception
2
+ # we also need to set err.$m to the right method table incase a subclass adds
3
+ # custom methods.. just get this from the klass: self.
4
+ def self.allocate
5
+ `var err = new Error();
6
+ err.$klass = self;
7
+ return err;`
8
+ end
9
+
10
+ def initialize(message = '')
11
+ @message = message
12
+ `return self.message = self.$klass.__classid__ + ': ' + message;`
13
+ end
14
+
15
+ def message
16
+ @message
17
+ end
18
+
19
+ def inspect
20
+ `return "#<" + self.$klass.__classid__ + ": '" + #{@message} + "'>";`
21
+ end
22
+
23
+ def to_s
24
+ @message
25
+ end
26
+ end
27
+
28
+ class StandardError < Exception; end
29
+ class RuntimeError < Exception; end
30
+ class LocalJumpError < StandardError; end
31
+ class TypeError < StandardError; end
32
+
33
+ class NameError < StandardError; end
34
+ class NoMethodError < NameError; end
35
+ class ArgumentError < StandardError; end
36
+
37
+ class ScriptError < Exception; end
38
+ class LoadError < ScriptError; end
39
+
40
+ class IndexError < StandardError; end
41
+ class KeyError < IndexError; end
42
+ class RangeError < StandardError; end
43
+
@@ -0,0 +1,21 @@
1
+ class FalseClass
2
+
3
+ def to_s
4
+ "false"
5
+ end
6
+
7
+ def &(other)
8
+ false
9
+ end
10
+
11
+ def |(other)
12
+ `return other.$r ? Qtrue : Qfalse;`
13
+ end
14
+
15
+ def ^(other)
16
+ `return other.$r ? Qtrue : Qfalse;`
17
+ end
18
+ end
19
+
20
+ FALSE = false
21
+
@@ -0,0 +1,54 @@
1
+
2
+ class File
3
+ # Use either the browser fs namespace or overriden gem interface.
4
+ `var OPAL_FS = VM.opal.fs;`
5
+
6
+ # Converts the given `file_name` into its absolute path. The current working
7
+ # directory is used as the reference unless the `dir_string` is given, in
8
+ # which case that is used.
9
+ #
10
+ # @param [String] file_name
11
+ # @param [String] dir_string
12
+ # @return [String]
13
+ def self.expand_path(file_name, dir_string)
14
+ `return OPAL_FS.expand_path(file_name, dir_string);`
15
+ end
16
+
17
+ # Returns a new string constructed by joining the given args with the default
18
+ # file separator.
19
+ #
20
+ # @param [String] str
21
+ # @return [String]
22
+ def self.join(*str)
23
+ `return OPAL_FS.join.apply(OPAL_FS, str);`
24
+ end
25
+
26
+ # Returns all the components of the given `file_name` except for the last
27
+ # one.
28
+ #
29
+ # @param [String] file_name
30
+ # @return [String]
31
+ def self.dirname(file_name)
32
+ `return OPAL_FS.dirname(file_name);`
33
+ end
34
+
35
+ # Returns the extension of the given filename.
36
+ #
37
+ # @param [String] file_name
38
+ # @return [String]
39
+ def self.extname(file_name)
40
+ `return OPAL_FS.extname(file_name);`
41
+ end
42
+
43
+ # Returns the last path component of the given `file_name`. If a suffix is
44
+ # given, and is present in the path, then it is removed. This is useful for
45
+ # removing file extensions, for example.
46
+ #
47
+ # @param [String] file_name
48
+ # @param [String] suffix
49
+ # @return [String]
50
+ def self.basename(file_name, suffix)
51
+ `return OPAL_FS.basename(file_name, suffix);`
52
+ end
53
+ end
54
+
@@ -0,0 +1,725 @@
1
+ # A Hash is a collection of key-value pairs. It is similar to an array except
2
+ # that indexing is done via arbitrary keys of any object type, not an integer
3
+ # index. Hahses enumerate their values in the order that the corresponding keys
4
+ # were inserted.
5
+ #
6
+ # Hashes have a default value that is returned when accessing keys that do not
7
+ # exist in the hash. By default, that valus is `nil`.
8
+ class Hash
9
+ # Returns a new array populated with the values from `self`.
10
+ #
11
+ # @example
12
+ #
13
+ # { :a => 1, :b => 2 }.values
14
+ # # => [1, 2]
15
+ #
16
+ # @return [Array]
17
+ def values
18
+ `var result = [], length = self.$keys.length;
19
+
20
+ for (var i = 0; i < length; i++) {
21
+ result.push(self.$assocs[self.$keys[i].$hash()]);
22
+ }
23
+
24
+ return result;`
25
+ end
26
+
27
+ # Returns the contents of this hash as a string.
28
+ #
29
+ # @example
30
+ #
31
+ # h = { 'a' => 100, 'b' => 200 }
32
+ # # => "{ \"a\" => 100, \"b\" => 200 }"
33
+ #
34
+ # @return [String]
35
+ def inspect
36
+ `var description = [], key, value;
37
+
38
+ for (var i = 0; i < self.$keys.length; i++) {
39
+ key = self.$keys[i];
40
+ value = self.$assocs[key.$hash()];
41
+ description.push(#{`key`.inspect} + '=>' + #{`value`.inspect});
42
+ }
43
+
44
+ return '{' + description.join(', ') + '}';`
45
+ end
46
+
47
+ # Returns a simple string representation of the hash's keys and values.
48
+ #
49
+ # @return [String]
50
+ def to_s
51
+ `var description = [], key, value;
52
+
53
+ for (var i = 0; i < self.$keys.length; i++) {
54
+ key = self.$keys[i];
55
+ value = self.$assocs[key.$hash()];
56
+ description.push(#{`key`.inspect} + #{`value`.inspect});
57
+ }
58
+
59
+ return description.join('');`
60
+ end
61
+
62
+ # Yields the block once for each key in `self`, passing the key-value pair
63
+ # as parameters.
64
+ #
65
+ # @example
66
+ #
67
+ # { 'a' => 100, 'b' => 200 }.each { |k, v| puts "#{k} is #{v}" }
68
+ # # => "a is 100"
69
+ # # => "b is 200"
70
+ #
71
+ # @return [Hash] returns the receiver
72
+ def each
73
+ `var keys = self.$keys, values = self.$assocs, length = keys.length, key;
74
+
75
+ for (var i = 0; i < length; i++) {
76
+ try {
77
+ key = keys[i];
78
+ #{yield `key`, `values[key.$hash()]`};
79
+ } catch (e) {
80
+ switch (e.$keyword) {
81
+ case 2:
82
+ return e['@exit_value'];
83
+ default:
84
+ throw e;
85
+ }
86
+ }
87
+ }
88
+
89
+ return self;`
90
+ end
91
+
92
+ # Searches through the hash comparing `obj` with the key ysing ==. Returns the
93
+ # key-value pair (two element array) or nil if no match is found.
94
+ #
95
+ # @example
96
+ #
97
+ # h = { 'a' => [1, 2, 3], 'b' => [4, 5, 6] }
98
+ # h.assoc 'a'
99
+ # # => ['a', [1, 2, 3]]
100
+ # h.assoc 'c'
101
+ # # => nil
102
+ #
103
+ # @param [Object] obj key to search for
104
+ # @return [Array<Object, Object>, nil] result or nil
105
+ def assoc(obj)
106
+ `var key, keys = self.$keys, length = keys.length;
107
+
108
+ for (var i = 0; i < length; i++) {
109
+ key = keys[i];
110
+ if (#{`key` == obj}.$r) {
111
+ return [key, self.$assocs[key.$hash()]];
112
+ }
113
+ }
114
+
115
+ return nil;`
116
+ end
117
+
118
+ # Equality - Two hashes are equal if they each contain the same number of keys
119
+ # and if each key-value paid is equal, accordind to {Object#==}, to the
120
+ # corresponding elements in the other hash.
121
+ #
122
+ # @example
123
+ #
124
+ # h1 = { 'a' => 1, 'c' => 2 }
125
+ # h2 = { 7 => 35, 'c' => 2, 'a' => 1 }
126
+ # h3 = { 'a' => 1, 'c' => 2, 7 => 35 }
127
+ # h4 = { 'a' => 1, 'd' => 2, 'f' => 35 }
128
+ #
129
+ # h1 == h2 # => false
130
+ # h2 == h3 # => true
131
+ # h3 == h4 # => false
132
+ #
133
+ # @param [Hash] other the hash to compare with
134
+ # @return [true, false]
135
+ def ==(other)
136
+ `if (self === other) return Qtrue;
137
+ if (!other.$keys || !other.$assocs) return Qfalse;
138
+ if (self.$keys.length != other.$keys.length) return Qfalse;
139
+
140
+ for (var i = 0; i < self.$keys.length; i++) {
141
+ var key1 = self.$keys[i], assoc1 = key1.$hash();
142
+
143
+ if (!other.$assocs.hasOwnProperty(assoc1))
144
+ return Qfalse;
145
+
146
+ var assoc2 = other.$assocs[assoc1];
147
+
148
+ if (!#{`self.$assocs[assoc1]` == `assoc2`}.$r)
149
+ return Qfalse;
150
+ }
151
+
152
+ return Qtrue;`
153
+ end
154
+
155
+ # Element reference - retrieves the `value` object corresponding to the `key`
156
+ # object. If not found, returns the default value.
157
+ #
158
+ # @example
159
+ #
160
+ # h = { 'a' => 100, 'b' => 200 }
161
+ # h['a']
162
+ # # => 100
163
+ # h['c']
164
+ # # => nil
165
+ #
166
+ # @param [Object] key the key to look for
167
+ # @return [Object] result or default value
168
+ def [](key)
169
+ `var assoc = key.$hash();
170
+
171
+ if (self.$assocs.hasOwnProperty(assoc))
172
+ return self.$assocs[assoc];
173
+
174
+ return self.$default;`
175
+ end
176
+
177
+ # Element assignment - Associates the value given by 'value' with the key
178
+ # given by 'key'. `key` should not have its value changed while it is used as
179
+ # a key.
180
+ #
181
+ # @example
182
+ #
183
+ # h = { 'a' => 100, 'b' => 200 }
184
+ # h['a'] = 9
185
+ # h['c'] = 4
186
+ # h
187
+ # # => { 'a' => 9, 'b' => 200, 'c' => 4 }
188
+ #
189
+ # @param [Object] key the key for hash
190
+ # @param [Object] value the value for the key
191
+ # @return [Object] returns the set value
192
+ def []=(key, value)
193
+ `var assoc = key.$hash();
194
+
195
+ if (!self.$assocs.hasOwnProperty(assoc))
196
+ self.$keys.push(key);
197
+
198
+ return self.$assocs[assoc] = value;`
199
+ end
200
+
201
+ # Remove all key-value pairs from `self`.
202
+ #
203
+ # @example
204
+ #
205
+ # h = { 'a' => 100, 'b' => 200 }
206
+ # h.clear
207
+ # # => {}
208
+ #
209
+ # @return [Hash]
210
+ def clear
211
+ `self.$keys = [];
212
+ self.$assocs = {};
213
+
214
+ return self;`
215
+ end
216
+
217
+ # Returns the default value for the hash.
218
+ def default
219
+ `return self.$default;`
220
+ end
221
+
222
+ # Sets the default value - the value returned when a key does not exist.
223
+ #
224
+ # @param [Object] obj the new default
225
+ # @return [Object] returns the new default
226
+ def default=(obj)
227
+ `return self.$default = obj;`
228
+ end
229
+
230
+ # Deletes and returns a key-value pair from self whose key is equal to `key`.
231
+ # If the key is not found, returns the default value. If the optional code
232
+ # block is given and the key is not found, pass in the key and return the
233
+ # result of the block.
234
+ #
235
+ # @example
236
+ #
237
+ # h = { 'a' => 100, 'b' => 200 }
238
+ # h.delete 'a'
239
+ # # => 100
240
+ # h.delete 'z'
241
+ # # => nil
242
+ #
243
+ # @param [Object] key the key to delete
244
+ # #return [Object] returns value or default value
245
+ def delete(key)
246
+ `var assoc = key.$hash();
247
+
248
+ if (self.$assocs.hasOwnProperty(assoc)) {
249
+ var ret = self.$assocs[assoc];
250
+ delete self.$assocs[assoc];
251
+ self.$keys.splice(self.$keys.indexOf(key), 1);
252
+ return ret;
253
+ }
254
+
255
+ return self.$default;`
256
+ end
257
+
258
+ # Deletes every key-value pair from `self` for which the block evaluates to
259
+ # `true`.
260
+ #
261
+ # @example
262
+ #
263
+ # h = { 'a' => 100, 'b' => 200, 'c' => 300 }
264
+ # h.delete_if { |k, v| key >= 'b' }
265
+ # # => { 'a' => 100 }
266
+ #
267
+ # @return [Hash] returns the receiver
268
+ def delete_if
269
+ `var key, value;
270
+
271
+ for (var i = 0; i < self.$keys.length; i++) {
272
+ try {
273
+ key = self.$keys[i];
274
+ value = self.$assocs[key.$hash()];
275
+
276
+ if (#{yield `key`, `value`}.$r) {
277
+ delete self.$assocs[key.$hash()];
278
+ self.$keys.splice(i, 1);
279
+ i--;
280
+ }
281
+ } catch (e) {
282
+ switch (e.$keyword) {
283
+ case 2:
284
+ return e['@exit_value'];
285
+ default:
286
+ throw e;
287
+ }
288
+ }
289
+ }
290
+
291
+ return self;`
292
+ end
293
+
294
+ # Yields the block once for each key in `self`, passing the key as a param.
295
+ #
296
+ # @example
297
+ #
298
+ # h = { 'a' => 100, 'b' => 200, 'c' => 300 }
299
+ # h.each_key { |key| puts key }
300
+ # # => 'a'
301
+ # # => 'b'
302
+ # # => 'c'
303
+ #
304
+ # @return [Hash] returns receiver
305
+ def each_key
306
+ `var key;
307
+
308
+ for (var i = 0; i < self.$keys.length; i++) {
309
+ try {
310
+ key = self.$keys[i];
311
+ #{yield `key`};
312
+ } catch (e) {
313
+ switch (e.$keyword) {
314
+ case 2:
315
+ return e['@exit_value'];
316
+ default:
317
+ throw e;
318
+ }
319
+ }
320
+ }
321
+
322
+ return self;`
323
+ end
324
+
325
+ # Yields the block once for each key in self, passing the associated value
326
+ # as a param.
327
+ #
328
+ # @example
329
+ #
330
+ # h = { 'a' => 100, 'b' => 200 }
331
+ # h.each_value { |a| puts a }
332
+ # # => 100
333
+ # # => 200
334
+ #
335
+ # @return [Hash] returns the receiver
336
+ def each_value
337
+ `var val;
338
+
339
+ for (var i = 0; i < self.$keys.length; i++) {
340
+ try {
341
+ val = self.$assocs[self.$keys[i].$hash()];
342
+ #{yield `val`};
343
+ } catch (e) {
344
+ switch (e.$keyword) {
345
+ case 2:
346
+ return e['@exit_value'];
347
+ default:
348
+ throw e;
349
+ }
350
+ }
351
+ }
352
+
353
+ return self;`
354
+ end
355
+
356
+ # Returns `true` if `self` contains no key-value pairs, `false` otherwise.
357
+ #
358
+ # @example
359
+ #
360
+ # {}.empty?
361
+ # # => true
362
+ #
363
+ # @return [true, false]
364
+ def empty?
365
+ `return self.$keys.length == 0 ? Qtrue : Qfalse;`
366
+ end
367
+
368
+ # Returns a value from the hash for the given key. If the key can't be found,
369
+ # there are several options; with no other argument, it will raise a
370
+ # KeyError exception; if default is given, then that will be returned, if the
371
+ # optional code block if specified, then that will be run and its value
372
+ # returned.
373
+ #
374
+ # @example
375
+ #
376
+ # h = { 'a' => 100, 'b' => 200 }
377
+ # h.fetch 'a' # => 100
378
+ # h.fetch 'z', 'wow' # => 'wow'
379
+ # h.fetch 'z' # => KeyError
380
+ #
381
+ # @param [Object] key the key to lookup
382
+ # @param [Object] defaults the default value to return
383
+ # @return [Object] value from hash
384
+ def fetch(key, defaults = `undefined`)
385
+ `var value = self.$assocs[key.$hash()];
386
+
387
+ if (value != undefined)
388
+ return value;
389
+ else if (defaults == undefined)
390
+ rb_raise('KeyError: key not found');
391
+ else
392
+ return defaults;`
393
+ end
394
+
395
+ # Returns a new array that is a one dimensional flattening of this hash. That
396
+ # is, for every key or value that is an array, extraxt its elements into the
397
+ # new array. Unlike {Array#flatten}, this method does not flatten
398
+ # recursively by default. The optional `level` argument determines the level
399
+ # of recursion to flatten.
400
+ #
401
+ # @example
402
+ #
403
+ # a = { 1 => 'one', 2 => [2, 'two'], 3 => 'three' }
404
+ # a.flatten
405
+ # # => [1, 'one', 2, [2, 'two'], 3, 'three']
406
+ # a.flatten(2)
407
+ # # => [1, 'one', 2, 2, 'two', 3, 'three']
408
+ #
409
+ # @param [Numeric] level the level to flatten until
410
+ # @return [Array] flattened hash
411
+ def flatten(level = 1)
412
+ `var result = [], key, value;
413
+
414
+ for (var i = 0; i < self.$keys.length; i++) {
415
+ key = self.$keys[i];
416
+ value = self.$assocs[key.$hash()];
417
+ result.push(key);
418
+
419
+ if (value instanceof Array) {
420
+ if (level == 1) {
421
+ result.push(value);
422
+ } else {
423
+ var tmp = #{`value`.flatten `level - 1`};
424
+ result = result.concat(tmp);
425
+ }
426
+ } else {
427
+ result.push(value);
428
+ }
429
+ }
430
+
431
+ return result;`
432
+ end
433
+
434
+ # Returns `true` if the given `key` is present in `self`.
435
+ #
436
+ # @example
437
+ #
438
+ # h = { 'a' => 100, 'b' => 200 }
439
+ # h.has_key? 'a'
440
+ # # => true
441
+ # h.has_key? 'c'
442
+ # # => false
443
+ #
444
+ # @param [Object] key the key to check
445
+ # @return [true, false]
446
+ def has_key?(key)
447
+ `if (self.$assocs.hasOwnProperty(key.$hash()))
448
+ return Qtrue;
449
+
450
+ return Qfalse;`
451
+ end
452
+
453
+ # Returns `true` if the given `value` is present for some key in `self`.
454
+ #
455
+ # @example
456
+ #
457
+ # h = { 'a' => 100 }
458
+ # h.has_value? 100
459
+ # # => true
460
+ # h.has_value? 2020
461
+ # # => false
462
+ #
463
+ # @param [Object] value the value to check for
464
+ # @return [true, false]
465
+ def has_value?(value)
466
+ `var key, value;
467
+
468
+ for (var i = 0; i < self.$keys.length; i++) {
469
+ key = self.$keys[i];
470
+ val = self.$assocs[key.$hash()];
471
+
472
+ if (#{`value` == `val`}.$r)
473
+ return Qtrue;
474
+ }
475
+
476
+ return Qfalse;`
477
+ end
478
+
479
+ # Replaces the contents of `self` with the contents of `other`.
480
+ #
481
+ # @example
482
+ #
483
+ # h = { 'a' => 100, 'b' => 200 }
484
+ # h.replace({ 'c' => 200, 'd' => 300 })
485
+ # # => { 'c' => 200, 'd' => 300 }
486
+ #
487
+ # @param [Hash] other hash to replace with
488
+ # @return [Hash] returns receiver
489
+ def replace(other)
490
+ `self.$keys = []; self.$assocs = {};
491
+
492
+ for (var i = 0; i < other.$keys.length; i++) {
493
+ var key = other.$keys[i];
494
+ var val = other.$assocs[key.$hash()];
495
+ self.$keys.push(key);
496
+ self.$assocs[key.$hash()] = val;
497
+ }
498
+
499
+ return self;`
500
+ end
501
+
502
+ # Returns a new hash created by using `self`'s vales as keys, and keys as
503
+ # values.
504
+ #
505
+ # @example
506
+ #
507
+ # h = { 'n' => 100, 'm' => 100, 'y' => 300 }
508
+ # h.invert
509
+ # # => { 100 => 'm', 300 => 'y' }
510
+ #
511
+ # @return [Hash] inverted hash
512
+ def invert
513
+
514
+ end
515
+
516
+ # Returns the key for the given value. If not found, returns `nil`.
517
+ #
518
+ # @example
519
+ #
520
+ # h = { 'a' => 100, 'b' => 200 }
521
+ # h.key 200
522
+ # # => 'b'
523
+ # h.key 300
524
+ # # => nil
525
+ #
526
+ # @param [Object] value the value to check for
527
+ # @return [Object] key or nil
528
+ def key(value)
529
+ `var key, val;
530
+
531
+ for (var i = 0; i < self.$keys.length; i++) {
532
+ key = self.$keys[i];
533
+ val = self.$assocs[key.$hash()];
534
+
535
+ if (#{`value` == `val`}.$r) {
536
+ return key;
537
+ }
538
+ }
539
+
540
+ return nil;`
541
+ end
542
+
543
+ # Returns a new array populated with the keys from this hash. See also
544
+ # {#values}.
545
+ #
546
+ # @example
547
+ #
548
+ # h = { 'a' => 100, 'b' => 200 }
549
+ # h.keys
550
+ # # => ['a', 'b']
551
+ #
552
+ # @return [Array]
553
+ def keys
554
+ `return self.$keys.slice(0);`
555
+ end
556
+
557
+ # Returns the number of key-value pairs in the hash.
558
+ #
559
+ # @example
560
+ #
561
+ # h = { 'a' => 100, 'b' => 200 }
562
+ # h.length
563
+ # # => 2
564
+ #
565
+ # @return [Numeric]
566
+ def length
567
+ `return self.$keys.length;`
568
+ end
569
+
570
+ # Returns a new hash containing the contents of `other` and `self`. If no
571
+ # block is specified, the value for the entries with duplicate keys will be
572
+ # that of `other`. Otherwise the value for each duplicate key is determined
573
+ # by calling the block with the key and its value in self, and its value in
574
+ # other.
575
+ #
576
+ # @example
577
+ #
578
+ # h1 = { 'a' => 100, 'b' => 200 }
579
+ # h2 = { 'b' => 300, 'c' => 400 }
580
+ # h1.merge h2
581
+ # # => {'a' => 100, 'b' => 300, 'c' => 400 }
582
+ # h1
583
+ # # => {'a' => 100, 'b' => 200}
584
+ #
585
+ # @param [Hash] other hash to merge with
586
+ # #return [Hash] returns new hash
587
+ def merge(other)
588
+ `var result = $opal.H() , key, val;
589
+
590
+ for (var i = 0; i < self.$keys.length; i++) {
591
+ key = self.$keys[i], val = self.$assocs[key.$hash()];
592
+
593
+ result.$keys.push(key);
594
+ result.$assocs[key.$hash()] = val;
595
+ }
596
+
597
+ for (var i = 0; i < other.$keys.length; i++) {
598
+ key = other.$keys[i], val = other.$assocs[key.$hash()];
599
+
600
+ if (!result.$assocs.hasOwnProperty(key.$hash())) {
601
+ result.$keys.push(key);
602
+ }
603
+
604
+ result.$assocs[key.$hash()] = val;
605
+ }
606
+
607
+ return result;`
608
+ end
609
+
610
+ # Merges the contents of `other` into `self`. If no block is given, entries
611
+ # with duplicate keys are overwritten with values from `other`.
612
+ #
613
+ # @example
614
+ #
615
+ # h1 = { 'a' => 100, 'b' => 200 }
616
+ # h2 = { 'b' => 300, 'c' => 400 }
617
+ # h1.merge! h2
618
+ # # => { 'a' => 100, 'b' => 300, 'c' => 400 }
619
+ # h1
620
+ # # => { 'a' => 100, 'b' => 300, 'c' => 400 }
621
+ #
622
+ # @param [Hash] other
623
+ # @return [Hash]
624
+ def merge!(other)
625
+ `var key, val;
626
+
627
+ for (var i = 0; i < other.$keys.length; i++) {
628
+ key = other.$keys[i];
629
+ val = other.$assocs[key.$hash()];
630
+
631
+ if (!self.$assocs.hasOwnProperty(key.$hash())) {
632
+ self.$keys.push(key);
633
+ }
634
+
635
+ self.$assocs[key.$hash()] = val;
636
+ }
637
+
638
+ return self;`
639
+ end
640
+
641
+ # Searches through the hash comparing `obj` with the value using ==. Returns
642
+ # the first key-value pair, as an array, that matches.
643
+ #
644
+ # @example
645
+ #
646
+ # a = { 1 => 'one', 2 => 'two', 3 => 'three' }
647
+ # a.rassoc 'two'
648
+ # # => [2, 'two']
649
+ # a.rassoc 'four'
650
+ # # => nil
651
+ #
652
+ # @param [Object] obj object to check
653
+ # @return [Array]
654
+ def rassoc(obj)
655
+ `var key, val;
656
+
657
+ for (var i = 0; i < self.$keys.length; i++) {
658
+ key = self.$keys[i];
659
+ val = self.$assocs[key.$hash()];
660
+
661
+ if (#{`val` == obj}.$r)
662
+ return [key, val];
663
+ }
664
+
665
+ return nil;`
666
+ end
667
+
668
+ # Removes a key-value pair from the hash and returns it as a two item array.
669
+ # Returns the default value if the hash is empty.
670
+ #
671
+ # @example
672
+ #
673
+ # h = { 'a' => 1, 'b' => 2 }
674
+ # h.shift
675
+ # # => ['a', 1]
676
+ # h
677
+ # # => { 'b' => 2 }
678
+ # {}.shift
679
+ # # => nil
680
+ #
681
+ # @return [Array, Object]
682
+ def shift
683
+ `var key, val;
684
+
685
+ if (self.$keys.length > 0) {
686
+ key = self.$keys[0];
687
+ val = self.$assocs[key.$hash()];
688
+
689
+ self.$keys.shift();
690
+ delete self.$assocs[key.$hash()];
691
+ return [key, val];
692
+ }
693
+
694
+ return self.$default;`
695
+ end
696
+
697
+ # Convert self into a nested array of `[key, value]` arrays.
698
+ #
699
+ # @example
700
+ #
701
+ # h = { 'a' => 1, 'b' => 2, 'c' => 3 }
702
+ # h.to_a
703
+ # # => [['a', 1], ['b', 2], ['c', 3]]
704
+ #
705
+ # @return [Array]
706
+ def to_a
707
+ `var result = [], key, value;
708
+
709
+ for (var i = 0; i < self.$keys.length; i++) {
710
+ key = self.$keys[i];
711
+ value = self.$assocs[key.$hash()];
712
+ result.push([key, value]);
713
+ }
714
+
715
+ return result;`
716
+ end
717
+
718
+ # Returns self.
719
+ #
720
+ # @return [Hash]
721
+ def to_hash
722
+ self
723
+ end
724
+ end
725
+