opal 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. data/.gitignore +5 -10
  2. data/LICENSE +75 -0
  3. data/README.md +55 -3
  4. data/Rakefile +62 -139
  5. data/bin/opal +7 -10
  6. data/gems/core/README.md +5 -0
  7. data/gems/core/Rakefile +7 -0
  8. data/gems/core/core.gemspec +13 -0
  9. data/gems/core/lib/core.rb +33 -0
  10. data/gems/core/lib/core/array.rb +1470 -0
  11. data/gems/core/lib/core/basic_object.rb +15 -0
  12. data/gems/core/lib/core/class.rb +31 -0
  13. data/gems/core/lib/core/dir.rb +26 -0
  14. data/gems/core/lib/core/error.rb +43 -0
  15. data/gems/core/lib/core/false_class.rb +21 -0
  16. data/gems/core/lib/core/file.rb +54 -0
  17. data/gems/core/lib/core/hash.rb +725 -0
  18. data/gems/core/lib/core/kernel.rb +240 -0
  19. data/gems/core/lib/core/module.rb +98 -0
  20. data/gems/core/lib/core/nil_class.rb +41 -0
  21. data/gems/core/lib/core/numeric.rb +370 -0
  22. data/gems/core/lib/core/proc.rb +11 -0
  23. data/gems/core/lib/core/range.rb +17 -0
  24. data/gems/core/lib/core/regexp.rb +18 -0
  25. data/gems/core/lib/core/string.rb +328 -0
  26. data/gems/core/lib/core/symbol.rb +15 -0
  27. data/gems/core/lib/core/top_self.rb +8 -0
  28. data/gems/core/lib/core/true_class.rb +20 -0
  29. data/gems/core/lib/core/vm.rb +16 -0
  30. data/{opals/opal/opal → gems/core}/spec/core/array/append_spec.rb +0 -0
  31. data/{opals/opal/opal → gems/core}/spec/core/array/assoc_spec.rb +0 -0
  32. data/{opals/opal/opal → gems/core}/spec/core/array/at_spec.rb +0 -0
  33. data/{opals/opal/opal → gems/core}/spec/core/array/clear_spec.rb +1 -1
  34. data/{opals/opal/opal → gems/core}/spec/core/array/collect_bang_spec.rb +0 -0
  35. data/{opals/opal/opal → gems/core}/spec/core/array/collect_spec.rb +0 -0
  36. data/gems/core/spec/core/array/compact_spec.rb +41 -0
  37. data/{opals/opal/opal → gems/core}/spec/core/array/concat_spec.rb +0 -0
  38. data/{opals/opal/opal → gems/core}/spec/core/array/constructor_spec.rb +0 -0
  39. data/{opals/opal/opal → gems/core}/spec/core/array/each_spec.rb +0 -0
  40. data/{opals/opal/opal → gems/core}/spec/core/array/element_reference_spec.rb +0 -0
  41. data/{opals/opal/opal → gems/core}/spec/core/array/first_spec.rb +1 -1
  42. data/{opals/opal/opal → gems/core}/spec/core/array/include_spec.rb +0 -0
  43. data/gems/core/spec/core/array/join_spec.rb +6 -0
  44. data/gems/core/spec/core/array/last_spec.rb +51 -0
  45. data/gems/core/spec/core/array/length_spec.rb +6 -0
  46. data/{opals/opal/opal → gems/core}/spec/core/array/map_spec.rb +2 -0
  47. data/gems/core/spec/core/array/reverse_spec.rb +6 -0
  48. data/{opals/opal/opal → gems/core}/spec/core/builtin_constants/builtin_constants_spec.rb +0 -0
  49. data/{opals/opal/opal → gems/core}/spec/core/false/and_spec.rb +0 -0
  50. data/{opals/opal/opal → gems/core}/spec/core/false/inspect_spec.rb +0 -0
  51. data/{opals/opal/opal → gems/core}/spec/core/false/or_spec.rb +0 -0
  52. data/{opals/opal/opal → gems/core}/spec/core/false/to_s_spec.rb +0 -0
  53. data/{opals/opal/opal → gems/core}/spec/core/false/xor_spec.rb +0 -0
  54. data/{opals/opal/opal → gems/core}/spec/core/file/join_spec.rb +1 -1
  55. data/gems/core/spec/core/hash/assoc_spec.rb +32 -0
  56. data/{opals/opal/opal → gems/core}/spec/core/kernel/instance_eval_spec.rb +0 -0
  57. data/{opals/opal/opal → gems/core}/spec/core/kernel/loop_spec.rb +0 -0
  58. data/{opals/opal/opal → gems/core}/spec/core/kernel/raise_spec.rb +0 -0
  59. data/{opals/opal/opal → gems/core}/spec/core/module/attr_accessor_spec.rb +0 -0
  60. data/{opals/opal/opal → gems/core}/spec/core/number/lt_spec.rb +0 -0
  61. data/gems/core/spec/core/string/sub_spec.rb +24 -0
  62. data/{opals/opal/opal → gems/core}/spec/core/true/and_spec.rb +0 -0
  63. data/{opals/opal/opal → gems/core}/spec/core/true/inspect_spec.rb +0 -0
  64. data/{opals/opal/opal → gems/core}/spec/core/true/or_spec.rb +0 -0
  65. data/{opals/opal/opal → gems/core}/spec/core/true/to_s_spec.rb +0 -0
  66. data/{opals/opal/opal → gems/core}/spec/core/true/xor_spec.rb +0 -0
  67. data/{opals/opal/opal → gems/core}/spec/language/and_spec.rb +2 -3
  68. data/{opals/opal/opal → gems/core}/spec/language/array_spec.rb +21 -5
  69. data/gems/core/spec/language/block_spec.rb +38 -0
  70. data/{opals/opal/opal → gems/core}/spec/language/break_spec.rb +0 -0
  71. data/gems/core/spec/language/case_spec.rb +103 -0
  72. data/{opals/opal/opal → gems/core}/spec/language/def_spec.rb +11 -1
  73. data/{opals/opal/opal → gems/core}/spec/language/eigenclass_spec.rb +0 -0
  74. data/gems/core/spec/language/file_spec.rb +13 -0
  75. data/gems/core/spec/language/fixtures/block.rb +21 -0
  76. data/gems/core/spec/language/fixtures/super.rb +293 -0
  77. data/{opals/opal/opal → gems/core}/spec/language/hash_spec.rb +0 -0
  78. data/{opals/opal/opal → gems/core}/spec/language/if_spec.rb +0 -0
  79. data/{opals/opal/opal → gems/core}/spec/language/loop_spec.rb +0 -0
  80. data/gems/core/spec/language/metaclass_spec.rb +21 -0
  81. data/{opals/opal/opal → gems/core}/spec/language/method_spec.rb +60 -0
  82. data/{opals/opal/opal → gems/core}/spec/language/next_spec.rb +0 -0
  83. data/{opals/opal/opal → gems/core}/spec/language/or_spec.rb +0 -0
  84. data/{opals/opal/opal → gems/core}/spec/language/redo_spec.rb +0 -0
  85. data/gems/core/spec/language/regexp_spec.rb +26 -0
  86. data/{opals/opal/opal → gems/core}/spec/language/rescue_spec.rb +0 -0
  87. data/{opals/opal/opal → gems/core}/spec/language/return_spec.rb +0 -0
  88. data/{opals/opal/opal → gems/core}/spec/language/string_spec.rb +0 -0
  89. data/gems/core/spec/language/super_spec.rb +32 -0
  90. data/{opals/opal/opal → gems/core}/spec/language/until_spec.rb +47 -47
  91. data/gems/core/spec/language/variables_spec.rb +155 -0
  92. data/{opals/opal/opal → gems/core}/spec/language/while_spec.rb +47 -47
  93. data/{opals/opal/opal → gems/core}/spec/spec_helper.rb +1 -1
  94. data/gems/core_fs/README.md +19 -0
  95. data/gems/dev/Rakefile +5 -0
  96. data/gems/dev/lib/dev.js +99 -0
  97. data/gems/dev/lib/dev/generator.js +1264 -0
  98. data/gems/dev/lib/dev/parser.js +979 -0
  99. data/gems/dev/lib/dev/ruby_parser.js +1088 -0
  100. data/gems/dev/lib/dev/ruby_parser.y +1267 -0
  101. data/gems/dev/lib/dev/string_scanner.js +38 -0
  102. data/gems/dev/tools/racc2js/README.md +39 -0
  103. data/gems/dev/tools/racc2js/math_parser.js +222 -0
  104. data/gems/dev/tools/racc2js/math_parser.rb +133 -0
  105. data/gems/dev/tools/racc2js/math_parser.y +28 -0
  106. data/gems/dev/tools/racc2js/parser.js +218 -0
  107. data/gems/dev/tools/racc2js/racc2js.rb +153 -0
  108. data/gems/json/README.md +4 -0
  109. data/gems/json/json.gemspec +14 -0
  110. data/gems/json/lib/json.rb +64 -0
  111. data/gems/json/lib/json/ext.rb +51 -0
  112. data/{opals/opal/browser/lib/browser/json_parse.js → gems/json/lib/json/json2.js} +197 -37
  113. data/gems/ospec/README.md +0 -0
  114. data/gems/ospec/lib/ospec.rb +6 -0
  115. data/gems/ospec/lib/ospec/autorun.rb +3 -0
  116. data/gems/ospec/lib/ospec/dsl.rb +15 -0
  117. data/gems/ospec/lib/ospec/example.rb +11 -0
  118. data/gems/ospec/lib/ospec/example/before_and_after_hooks.rb +56 -0
  119. data/gems/ospec/lib/ospec/example/errors.rb +17 -0
  120. data/gems/ospec/lib/ospec/example/example_group.rb +12 -0
  121. data/gems/ospec/lib/ospec/example/example_group_factory.rb +21 -0
  122. data/gems/ospec/lib/ospec/example/example_group_hierarchy.rb +20 -0
  123. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/example/example_group_methods.rb +26 -68
  124. data/gems/ospec/lib/ospec/example/example_group_proxy.rb +14 -0
  125. data/gems/ospec/lib/ospec/example/example_methods.rb +46 -0
  126. data/gems/ospec/lib/ospec/example/example_proxy.rb +18 -0
  127. data/gems/ospec/lib/ospec/expectations.rb +19 -0
  128. data/gems/ospec/lib/ospec/expectations/errors.rb +8 -0
  129. data/gems/ospec/lib/ospec/expectations/fail_with.rb +8 -0
  130. data/gems/ospec/lib/ospec/expectations/handler.rb +27 -0
  131. data/gems/ospec/lib/ospec/matchers.rb +24 -0
  132. data/{opals/opal/Rakefile → gems/ospec/lib/ospec/matchers/be.rb} +0 -0
  133. data/gems/ospec/lib/ospec/matchers/generated_descriptions.rb +20 -0
  134. data/gems/ospec/lib/ospec/matchers/operator_matcher.rb +52 -0
  135. data/gems/ospec/lib/ospec/runner.rb +40 -0
  136. data/gems/ospec/lib/ospec/runner/example_group_runner.rb +44 -0
  137. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/runner/formatter/html_formatter.rb +31 -40
  138. data/gems/ospec/lib/ospec/runner/formatter/terminal_formatter.rb +48 -0
  139. data/gems/ospec/lib/ospec/runner/options.rb +36 -0
  140. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/runner/reporter.rb +23 -55
  141. data/gems/ospec/ospec.gemspec +0 -0
  142. data/gems/rquery/README.md +9 -0
  143. data/gems/rquery/lib/rquery.rb +10 -0
  144. data/gems/rquery/lib/rquery/ajax.rb +4 -0
  145. data/gems/rquery/lib/rquery/css.rb +96 -0
  146. data/gems/rquery/lib/rquery/document.rb +25 -0
  147. data/gems/rquery/lib/rquery/element.rb +292 -0
  148. data/gems/rquery/lib/rquery/event.rb +108 -0
  149. data/gems/rquery/lib/rquery/jquery.js +8177 -0
  150. data/gems/rquery/lib/rquery/request.rb +138 -0
  151. data/gems/rquery/lib/rquery/response.rb +49 -0
  152. data/gems/rquery/rquery.gemspec +16 -0
  153. data/lib/opal.js +1597 -0
  154. data/lib/opal.rb +6 -69
  155. data/lib/opal/builder.rb +115 -0
  156. data/lib/opal/bundle.rb +131 -0
  157. data/lib/opal/command.rb +11 -0
  158. data/lib/opal/context.rb +69 -0
  159. data/lib/opal/context/console.rb +12 -0
  160. data/lib/opal/context/file_system.rb +19 -0
  161. data/lib/opal/context/loader.rb +117 -0
  162. data/lib/opal/gem.rb +153 -0
  163. data/lib/opal/ruby/nodes.rb +1302 -0
  164. data/lib/opal/ruby/parser.rb +780 -0
  165. data/lib/opal/ruby/ruby_parser.rb +5170 -0
  166. data/lib/opal/ruby/ruby_parser.y +1298 -0
  167. data/opal.gemspec +11 -256
  168. metadata +179 -240
  169. data/.gitmodules +0 -6
  170. data/Opalfile +0 -384
  171. data/VERSION +0 -1
  172. data/demos/apps/browser_demo/index.html +0 -11
  173. data/demos/apps/browser_demo/lib/browser_demo.rb +0 -31
  174. data/demos/apps/simple_opal/Opalfile +0 -13
  175. data/demos/apps/simple_opal/index.html +0 -11
  176. data/demos/apps/simple_opal/lib/app_controller.rb +0 -62
  177. data/demos/apps/simple_opal/lib/main_window.rb +0 -146
  178. data/demos/browser/request/index.html +0 -52
  179. data/demos/browser/request/request.rb +0 -48
  180. data/gen/browser/__PROJECT_NAME__/Rakefile +0 -12
  181. data/gen/browser/__PROJECT_NAME__/index.html +0 -11
  182. data/gen/browser/__PROJECT_NAME__/javascripts/opal.debug.js +0 -4687
  183. data/gen/browser/__PROJECT_NAME__/javascripts/opal.min.js +0 -175
  184. data/gen/browser/__PROJECT_NAME__/lib/__PROJECT_NAME__.rb +0 -1
  185. data/lib/opal/builders/base.rb +0 -50
  186. data/lib/opal/builders/css.rb +0 -46
  187. data/lib/opal/builders/javascript.rb +0 -44
  188. data/lib/opal/builders/opal.rb +0 -79
  189. data/lib/opal/builders/ruby.rb +0 -50
  190. data/lib/opal/builders/ruby/generate.rb +0 -1851
  191. data/lib/opal/builders/ruby/nodes.rb +0 -210
  192. data/lib/opal/builders/ruby/ruby.rb +0 -916
  193. data/lib/opal/builders/ruby/ruby_parser.rb +0 -6008
  194. data/lib/opal/builders/ruby/ruby_parser.rb.y +0 -1451
  195. data/lib/opal/models/build_item.rb +0 -104
  196. data/lib/opal/models/hash_struct.rb +0 -40
  197. data/lib/opal/models/project.rb +0 -252
  198. data/lib/opal/models/struct_accessors.rb +0 -58
  199. data/lib/opal/models/target.rb +0 -176
  200. data/lib/opal/opal/build.rb +0 -169
  201. data/lib/opal/opal/env/console.rb +0 -66
  202. data/lib/opal/opal/env/fs.rb +0 -98
  203. data/lib/opal/opal/env/object.rb +0 -48
  204. data/lib/opal/opal/environment.rb +0 -139
  205. data/lib/opal/opal/gen.rb +0 -62
  206. data/lib/opal/opal/opal.rb +0 -75
  207. data/lib/opal/opal/repl.rb +0 -38
  208. data/lib/opal/opalfile/dsl.rb +0 -62
  209. data/lib/opal/opalfile/opalfile.rb +0 -133
  210. data/lib/opal/opalfile/task.rb +0 -96
  211. data/lib/opal/opalfile/task_manager.rb +0 -63
  212. data/lib/opal/opalfile/task_scope.rb +0 -52
  213. data/lib/opal/rack/app_server.rb +0 -119
  214. data/lib/opal/rake/opal_task.rb +0 -34
  215. data/opals/opal/README.md +0 -37
  216. data/opals/opal/browser/Opalfile +0 -11
  217. data/opals/opal/browser/README.md +0 -146
  218. data/opals/opal/browser/SIZZLE_LICESNSE.txt +0 -148
  219. data/opals/opal/browser/lib/browser.rb +0 -118
  220. data/opals/opal/browser/lib/browser/builder.rb +0 -41
  221. data/opals/opal/browser/lib/browser/canvas_context.rb +0 -115
  222. data/opals/opal/browser/lib/browser/dimensions.rb +0 -50
  223. data/opals/opal/browser/lib/browser/document.rb +0 -146
  224. data/opals/opal/browser/lib/browser/element.rb +0 -487
  225. data/opals/opal/browser/lib/browser/element/attributes.rb +0 -88
  226. data/opals/opal/browser/lib/browser/element/css.rb +0 -290
  227. data/opals/opal/browser/lib/browser/element/form.rb +0 -146
  228. data/opals/opal/browser/lib/browser/event/dom_events.rb +0 -81
  229. data/opals/opal/browser/lib/browser/event/event.rb +0 -177
  230. data/opals/opal/browser/lib/browser/event/trigger_events.rb +0 -53
  231. data/opals/opal/browser/lib/browser/geometry.rb +0 -97
  232. data/opals/opal/browser/lib/browser/json.rb +0 -32
  233. data/opals/opal/browser/lib/browser/request/request.rb +0 -201
  234. data/opals/opal/browser/lib/browser/sizzle.js +0 -1068
  235. data/opals/opal/browser/lib/browser/string.rb +0 -42
  236. data/opals/opal/browser/lib/browser/touch.rb +0 -37
  237. data/opals/opal/browser/lib/browser/vml_context.js +0 -33
  238. data/opals/opal/browser/lib/browser/window.rb +0 -36
  239. data/opals/opal/browser/spec/browser/browser_detection_spec.rb +0 -7
  240. data/opals/opal/browser/spec/document/aref_spec.rb +0 -110
  241. data/opals/opal/browser/spec/document/ready_spec.rb +0 -16
  242. data/opals/opal/browser/spec/element/body_spec.rb +0 -11
  243. data/opals/opal/browser/spec/element/clear_spec.rb +0 -26
  244. data/opals/opal/browser/spec/element/empty_spec.rb +0 -29
  245. data/opals/opal/browser/spec/element/has_class_spec.rb +0 -40
  246. data/opals/opal/browser/spec/element/hidden_spec.rb +0 -23
  247. data/opals/opal/browser/spec/element/hide_spec.rb +0 -31
  248. data/opals/opal/browser/spec/element/remove_spec.rb +0 -25
  249. data/opals/opal/browser/spec/element/show_spec.rb +0 -31
  250. data/opals/opal/browser/spec/element/style_spec.rb +0 -69
  251. data/opals/opal/browser/spec/element/toggle_spec.rb +0 -31
  252. data/opals/opal/browser/spec/element/visible_spec.rb +0 -23
  253. data/opals/opal/browser/spec/spec_helper.rb +0 -1
  254. data/opals/opal/opal/Opalfile +0 -14
  255. data/opals/opal/opal/spec/core/array/compact_spec.rb +0 -15
  256. data/opals/opal/opal/spec/fixtures/super.rb +0 -70
  257. data/opals/opal/opal/spec/language/____temp_remove_this.rb +0 -12
  258. data/opals/opal/opal/spec/language/block_spec.rb +0 -18
  259. data/opals/opal/opal/spec/language/case_spec.rb +0 -103
  260. data/opals/opal/opal/spec/language/metaclass_spec.rb +0 -21
  261. data/opals/opal/opal/spec/language/super_spec.rb +0 -26
  262. data/opals/opal/runtime/Opalfile +0 -78
  263. data/opals/opal/runtime/README.md +0 -12
  264. data/opals/opal/runtime/docs/debugging.md +0 -51
  265. data/opals/opal/runtime/lib/array.rb +0 -1516
  266. data/opals/opal/runtime/lib/basic_object.rb +0 -49
  267. data/opals/opal/runtime/lib/class.rb +0 -54
  268. data/opals/opal/runtime/lib/dir.rb +0 -36
  269. data/opals/opal/runtime/lib/error.rb +0 -49
  270. data/opals/opal/runtime/lib/false_class.rb +0 -52
  271. data/opals/opal/runtime/lib/file.rb +0 -79
  272. data/opals/opal/runtime/lib/hash.rb +0 -791
  273. data/opals/opal/runtime/lib/io.rb +0 -39
  274. data/opals/opal/runtime/lib/kernel.rb +0 -288
  275. data/opals/opal/runtime/lib/match_data.rb +0 -36
  276. data/opals/opal/runtime/lib/module.rb +0 -109
  277. data/opals/opal/runtime/lib/nil_class.rb +0 -69
  278. data/opals/opal/runtime/lib/number.rb +0 -398
  279. data/opals/opal/runtime/lib/proc.rb +0 -77
  280. data/opals/opal/runtime/lib/range.rb +0 -63
  281. data/opals/opal/runtime/lib/regexp.rb +0 -111
  282. data/opals/opal/runtime/lib/ruby.rb +0 -30
  283. data/opals/opal/runtime/lib/string.rb +0 -328
  284. data/opals/opal/runtime/lib/symbol.rb +0 -40
  285. data/opals/opal/runtime/lib/top_self.rb +0 -33
  286. data/opals/opal/runtime/lib/true_class.rb +0 -45
  287. data/opals/opal/runtime/runtime/browser.js +0 -287
  288. data/opals/opal/runtime/runtime/debug.js +0 -180
  289. data/opals/opal/runtime/runtime/opal.js +0 -1008
  290. data/opals/opal/runtime/runtime/post_opal.js +0 -1
  291. data/opals/opal/runtime/runtime/pre_opal.js +0 -2
  292. data/opals/opal/runtime/runtime/server_side.js +0 -50
  293. data/opals/opal/spec/LICENSE.txt +0 -26
  294. data/opals/opal/spec/Opalfile +0 -5
  295. data/opals/opal/spec/bin/spec.rb +0 -43
  296. data/opals/opal/spec/lib/spec.rb +0 -33
  297. data/opals/opal/spec/lib/spec/dsl.rb +0 -41
  298. data/opals/opal/spec/lib/spec/example.rb +0 -35
  299. data/opals/opal/spec/lib/spec/example/before_and_after_hooks.rb +0 -81
  300. data/opals/opal/spec/lib/spec/example/errors.rb +0 -42
  301. data/opals/opal/spec/lib/spec/example/example_group.rb +0 -37
  302. data/opals/opal/spec/lib/spec/example/example_group_factory.rb +0 -43
  303. data/opals/opal/spec/lib/spec/example/example_group_hierarchy.rb +0 -45
  304. data/opals/opal/spec/lib/spec/example/example_group_proxy.rb +0 -41
  305. data/opals/opal/spec/lib/spec/example/example_methods.rb +0 -73
  306. data/opals/opal/spec/lib/spec/example/example_proxy.rb +0 -48
  307. data/opals/opal/spec/lib/spec/expectations.rb +0 -46
  308. data/opals/opal/spec/lib/spec/expectations/errors.rb +0 -35
  309. data/opals/opal/spec/lib/spec/expectations/fail_with.rb +0 -37
  310. data/opals/opal/spec/lib/spec/expectations/handler.rb +0 -48
  311. data/opals/opal/spec/lib/spec/matchers.rb +0 -50
  312. data/opals/opal/spec/lib/spec/matchers/be.rb +0 -26
  313. data/opals/opal/spec/lib/spec/matchers/generated_descriptions.rb +0 -47
  314. data/opals/opal/spec/lib/spec/matchers/operator_matcher.rb +0 -66
  315. data/opals/opal/spec/lib/spec/runner.rb +0 -48
  316. data/opals/opal/spec/lib/spec/runner/example_group_runner.rb +0 -71
  317. data/opals/opal/spec/lib/spec/runner/formatter/terminal_formatter.rb +0 -82
  318. data/opals/opal/spec/lib/spec/runner/options.rb +0 -63
  319. data/opals/opal/spec/resources/index.html +0 -25
  320. data/opals/opal/spec/resources/spec.css +0 -132
  321. data/spec/cherry_kit/iseq_spec.rb +0 -38
  322. data/spec/spec_helper.rb +0 -16
  323. data/spec/vienna_spec.rb +0 -7
  324. data/yard/index.html +0 -43
  325. data/yard/style.css +0 -765
@@ -0,0 +1,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
+