opal 0.8.1 → 0.9.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 (331) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -2
  3. data/.gitmodules +3 -3
  4. data/.jshintrc +17 -20
  5. data/.travis.yml +22 -11
  6. data/CHANGELOG.md +51 -1
  7. data/CODE_OF_CONDUCT.md +15 -0
  8. data/CONTRIBUTING.md +125 -9
  9. data/Gemfile +1 -1
  10. data/Guardfile +2 -2
  11. data/README.md +95 -29
  12. data/Rakefile +1 -1
  13. data/benchmark/benchmarks +103 -0
  14. data/benchmark/bm_array_flatten.rb +9 -0
  15. data/benchmark/bm_array_intersection_numbers.rb +7 -0
  16. data/benchmark/bm_array_intersection_objects.rb +7 -0
  17. data/benchmark/bm_array_intersection_strings.rb +7 -0
  18. data/benchmark/bm_array_join_ary.rb +9 -0
  19. data/benchmark/bm_array_minus_numbers.rb +7 -0
  20. data/benchmark/bm_array_minus_objects.rb +7 -0
  21. data/benchmark/bm_array_minus_strings.rb +7 -0
  22. data/benchmark/bm_array_union_numbers.rb +7 -0
  23. data/benchmark/bm_array_union_objects.rb +7 -0
  24. data/benchmark/bm_array_union_strings.rb +7 -0
  25. data/benchmark/bm_array_uniq_bang_numbers.rb +5 -0
  26. data/benchmark/bm_array_uniq_bang_objects.rb +5 -0
  27. data/benchmark/bm_array_uniq_bang_strings.rb +5 -0
  28. data/benchmark/bm_array_uniq_numbers.rb +5 -0
  29. data/benchmark/bm_array_uniq_objects.rb +5 -0
  30. data/benchmark/bm_array_uniq_strings.rb +5 -0
  31. data/benchmark/bm_dispatch_bind_table.rb +57 -0
  32. data/benchmark/bm_dispatch_code_gen.rb +65 -0
  33. data/benchmark/bm_dispatch_code_gen_if.rb +64 -0
  34. data/benchmark/bm_dispatch_hardcoded.rb +44 -0
  35. data/benchmark/bm_dispatch_send.rb +38 -0
  36. data/benchmark/bm_dispatch_send_table.rb +57 -0
  37. data/benchmark/bm_hash_assoc_object.rb +11 -0
  38. data/benchmark/bm_hash_assoc_string.rb +9 -0
  39. data/benchmark/bm_hash_clone_object.rb +9 -0
  40. data/benchmark/bm_hash_clone_string.rb +9 -0
  41. data/benchmark/bm_hash_delete_object.rb +11 -0
  42. data/benchmark/bm_hash_delete_string.rb +9 -0
  43. data/benchmark/bm_hash_each_key_object.rb +9 -0
  44. data/benchmark/bm_hash_each_key_string.rb +9 -0
  45. data/benchmark/bm_hash_each_object.rb +9 -0
  46. data/benchmark/bm_hash_each_string.rb +9 -0
  47. data/benchmark/bm_hash_each_value_object.rb +9 -0
  48. data/benchmark/bm_hash_each_value_string.rb +9 -0
  49. data/benchmark/bm_hash_element_reference_object.rb +11 -0
  50. data/benchmark/bm_hash_element_reference_string.rb +9 -0
  51. data/benchmark/bm_hash_element_set_object.rb +5 -0
  52. data/benchmark/bm_hash_element_set_string.rb +5 -0
  53. data/benchmark/bm_hash_equal_value_object.rb +14 -0
  54. data/benchmark/bm_hash_equal_value_string.rb +11 -0
  55. data/benchmark/bm_hash_fetch_object.rb +11 -0
  56. data/benchmark/bm_hash_fetch_string.rb +9 -0
  57. data/benchmark/bm_hash_flatten_object.rb +9 -0
  58. data/benchmark/bm_hash_flatten_string.rb +9 -0
  59. data/benchmark/bm_hash_has_key_object.rb +11 -0
  60. data/benchmark/bm_hash_has_key_string.rb +9 -0
  61. data/benchmark/bm_hash_has_value_object.rb +9 -0
  62. data/benchmark/bm_hash_has_value_string.rb +9 -0
  63. data/benchmark/bm_hash_hash_object.rb +9 -0
  64. data/benchmark/bm_hash_hash_string.rb +9 -0
  65. data/benchmark/bm_hash_inspect_object.rb +9 -0
  66. data/benchmark/bm_hash_inspect_string.rb +9 -0
  67. data/benchmark/bm_hash_invert_object.rb +9 -0
  68. data/benchmark/bm_hash_invert_string.rb +9 -0
  69. data/benchmark/bm_hash_keep_if_object.rb +9 -0
  70. data/benchmark/bm_hash_keep_if_string.rb +9 -0
  71. data/benchmark/bm_hash_key_object.rb +9 -0
  72. data/benchmark/bm_hash_key_string.rb +9 -0
  73. data/benchmark/bm_hash_keys_object.rb +9 -0
  74. data/benchmark/bm_hash_keys_string.rb +9 -0
  75. data/benchmark/bm_hash_literal_mixed_large.rb +3 -0
  76. data/benchmark/bm_hash_literal_mixed_small.rb +3 -0
  77. data/benchmark/bm_hash_literal_object_large.rb +4 -0
  78. data/benchmark/bm_hash_literal_object_small.rb +3 -0
  79. data/benchmark/bm_hash_literal_string_large.rb +4 -0
  80. data/benchmark/bm_hash_literal_string_small.rb +3 -0
  81. data/benchmark/bm_hash_merge_object.rb +22 -0
  82. data/benchmark/bm_hash_merge_string.rb +18 -0
  83. data/benchmark/bm_hash_rassoc_object.rb +9 -0
  84. data/benchmark/bm_hash_rassoc_string.rb +9 -0
  85. data/benchmark/bm_hash_rehash_object.rb +9 -0
  86. data/benchmark/bm_hash_rehash_string.rb +9 -0
  87. data/benchmark/bm_hash_reject_bang_object.rb +9 -0
  88. data/benchmark/bm_hash_reject_bang_string.rb +9 -0
  89. data/benchmark/bm_hash_reject_object.rb +9 -0
  90. data/benchmark/bm_hash_reject_string.rb +9 -0
  91. data/benchmark/bm_hash_replace_object.rb +18 -0
  92. data/benchmark/bm_hash_replace_string.rb +14 -0
  93. data/benchmark/bm_hash_select_bang_object.rb +9 -0
  94. data/benchmark/bm_hash_select_bang_string.rb +9 -0
  95. data/benchmark/bm_hash_select_object.rb +9 -0
  96. data/benchmark/bm_hash_select_string.rb +9 -0
  97. data/benchmark/bm_hash_shift_object.rb +10 -0
  98. data/benchmark/bm_hash_shift_string.rb +10 -0
  99. data/benchmark/bm_hash_to_a_object.rb +9 -0
  100. data/benchmark/bm_hash_to_a_string.rb +9 -0
  101. data/benchmark/bm_hash_to_h_object.rb +10 -0
  102. data/benchmark/bm_hash_to_h_string.rb +10 -0
  103. data/benchmark/bm_hash_values_object.rb +9 -0
  104. data/benchmark/bm_hash_values_string.rb +9 -0
  105. data/benchmark/run.rb +48 -0
  106. data/bin/opal-mspec +1 -1
  107. data/bin/opal-repl +4 -4
  108. data/docs/compiled_ruby.md +214 -56
  109. data/docs/configuring_gems.md +2 -2
  110. data/docs/faq.md +2 -2
  111. data/docs/getting_started.md +19 -2
  112. data/docs/jquery.md +5 -5
  113. data/docs/opal_parser.md +53 -0
  114. data/docs/unsupported_features.md +2 -2
  115. data/docs/upgrading.md +22 -0
  116. data/docs/using_sprockets.md +15 -0
  117. data/examples/rack/config.ru +13 -0
  118. data/examples/sinatra/config.ru +4 -5
  119. data/lib/mspec/opal/runner.rb +54 -11
  120. data/lib/opal.rb +1 -1
  121. data/lib/opal/builder.rb +1 -1
  122. data/lib/opal/builder_processors.rb +1 -1
  123. data/lib/opal/cli.rb +17 -13
  124. data/lib/opal/cli_options.rb +1 -1
  125. data/lib/opal/compiler.rb +12 -0
  126. data/lib/opal/config.rb +4 -0
  127. data/lib/opal/nodes/arglist.rb +5 -7
  128. data/lib/opal/nodes/call.rb +6 -1
  129. data/lib/opal/nodes/call_special.rb +74 -0
  130. data/lib/opal/nodes/def.rb +35 -28
  131. data/lib/opal/nodes/definitions.rb +3 -5
  132. data/lib/opal/nodes/for.rb +13 -0
  133. data/lib/opal/nodes/helpers.rb +15 -1
  134. data/lib/opal/nodes/if.rb +5 -5
  135. data/lib/opal/nodes/iter.rb +6 -1
  136. data/lib/opal/nodes/literal.rb +1 -1
  137. data/lib/opal/nodes/logic.rb +2 -2
  138. data/lib/opal/nodes/masgn.rb +1 -2
  139. data/lib/opal/nodes/module.rb +2 -1
  140. data/lib/opal/nodes/rescue.rb +10 -1
  141. data/lib/opal/nodes/scope.rb +8 -2
  142. data/lib/opal/nodes/singleton_class.rb +1 -1
  143. data/lib/opal/nodes/top.rb +11 -0
  144. data/lib/opal/nodes/variables.rb +4 -4
  145. data/lib/opal/parser.rb +21 -3
  146. data/lib/opal/parser/grammar.rb +3115 -2961
  147. data/lib/opal/parser/grammar.y +29 -6
  148. data/lib/opal/parser/lexer.rb +18 -8
  149. data/lib/opal/sprockets.rb +85 -0
  150. data/lib/opal/sprockets/processor.rb +11 -35
  151. data/lib/opal/sprockets/server.rb +3 -15
  152. data/lib/opal/version.rb +2 -2
  153. data/opal.gemspec +4 -4
  154. data/opal/README.md +9 -0
  155. data/opal/corelib/array.rb +433 -181
  156. data/opal/corelib/basic_object.rb +48 -4
  157. data/opal/corelib/boolean.rb +15 -6
  158. data/opal/corelib/class.rb +6 -5
  159. data/opal/corelib/comparable.rb +12 -0
  160. data/opal/corelib/complex.rb +282 -0
  161. data/opal/corelib/constants.rb +9 -0
  162. data/opal/corelib/enumerable.rb +83 -34
  163. data/opal/corelib/enumerator.rb +3 -1
  164. data/opal/corelib/error.rb +49 -10
  165. data/opal/corelib/file.rb +1 -0
  166. data/opal/corelib/hash.rb +353 -577
  167. data/opal/corelib/helpers.rb +20 -0
  168. data/opal/corelib/kernel.rb +114 -59
  169. data/opal/corelib/math.rb +470 -0
  170. data/opal/corelib/method.rb +11 -2
  171. data/opal/corelib/module.rb +96 -96
  172. data/opal/corelib/{nil_class.rb → nil.rb} +20 -1
  173. data/opal/corelib/number.rb +751 -0
  174. data/opal/corelib/numeric.rb +77 -437
  175. data/opal/corelib/proc.rb +81 -1
  176. data/opal/corelib/process.rb +27 -0
  177. data/opal/corelib/rational.rb +358 -0
  178. data/opal/corelib/regexp.rb +156 -27
  179. data/opal/corelib/runtime.js +724 -335
  180. data/opal/corelib/string.rb +93 -104
  181. data/opal/corelib/string/encoding.rb +177 -0
  182. data/opal/corelib/string/inheritance.rb +2 -0
  183. data/opal/corelib/struct.rb +105 -18
  184. data/opal/corelib/time.rb +267 -146
  185. data/opal/corelib/unsupported.rb +216 -0
  186. data/opal/corelib/variables.rb +0 -6
  187. data/opal/opal.rb +8 -22
  188. data/opal/opal/base.rb +9 -0
  189. data/opal/opal/mini.rb +17 -0
  190. data/spec/README.md +1 -1
  191. data/spec/filters/bugs/array.rb +38 -136
  192. data/spec/filters/bugs/{basic_object.rb → basicobject.rb} +14 -15
  193. data/spec/filters/bugs/class.rb +6 -12
  194. data/spec/filters/bugs/complex.rb +3 -0
  195. data/spec/filters/bugs/date.rb +162 -10
  196. data/spec/filters/bugs/enumerable.rb +31 -58
  197. data/spec/filters/bugs/enumerator.rb +42 -0
  198. data/spec/filters/bugs/exception.rb +66 -10
  199. data/spec/filters/bugs/float.rb +17 -0
  200. data/spec/filters/bugs/hash.rb +11 -97
  201. data/spec/filters/bugs/inheritance.rb +5 -0
  202. data/spec/filters/bugs/integer.rb +28 -0
  203. data/spec/filters/bugs/kernel.rb +304 -12
  204. data/spec/filters/bugs/language.rb +133 -399
  205. data/spec/filters/bugs/language_opal.rb +88 -0
  206. data/spec/filters/bugs/module.rb +203 -62
  207. data/spec/filters/bugs/numeric.rb +32 -0
  208. data/spec/filters/bugs/proc.rb +39 -0
  209. data/spec/filters/bugs/range.rb +148 -0
  210. data/spec/filters/bugs/regexp.rb +168 -0
  211. data/spec/filters/bugs/set.rb +46 -3
  212. data/spec/filters/bugs/singleton.rb +1 -2
  213. data/spec/filters/bugs/string.rb +59 -90
  214. data/spec/filters/bugs/strscan.rb +80 -0
  215. data/spec/filters/bugs/struct.rb +10 -20
  216. data/spec/filters/bugs/time.rb +17 -184
  217. data/spec/filters/bugs/unboundmethod.rb +22 -0
  218. data/spec/filters/unsupported/array.rb +163 -0
  219. data/spec/filters/unsupported/basicobject.rb +14 -0
  220. data/spec/filters/unsupported/bignum.rb +46 -0
  221. data/spec/filters/unsupported/class.rb +4 -0
  222. data/spec/filters/unsupported/delegator.rb +5 -0
  223. data/spec/filters/unsupported/enumerable.rb +11 -0
  224. data/spec/filters/unsupported/enumerator.rb +8 -9
  225. data/spec/filters/unsupported/fixnum.rb +14 -0
  226. data/spec/filters/unsupported/float.rb +41 -7
  227. data/spec/filters/unsupported/freeze.rb +45 -0
  228. data/spec/filters/unsupported/hash.rb +50 -0
  229. data/spec/filters/unsupported/integer.rb +3 -0
  230. data/spec/filters/unsupported/kernel.rb +31 -0
  231. data/spec/filters/unsupported/language.rb +17 -0
  232. data/spec/filters/unsupported/matchdata.rb +30 -0
  233. data/spec/filters/unsupported/math.rb +3 -0
  234. data/spec/filters/unsupported/module.rb +5 -3
  235. data/spec/filters/unsupported/pathname.rb +3 -0
  236. data/spec/filters/unsupported/privacy.rb +136 -0
  237. data/spec/filters/unsupported/proc.rb +3 -0
  238. data/spec/filters/unsupported/regexp.rb +59 -0
  239. data/spec/filters/unsupported/set.rb +4 -0
  240. data/spec/filters/unsupported/{marshal.rb → singleton.rb} +4 -2
  241. data/spec/filters/unsupported/{mutable_strings.rb → string.rb} +456 -336
  242. data/spec/filters/unsupported/struct.rb +3 -0
  243. data/spec/filters/unsupported/symbol.rb +5 -0
  244. data/spec/filters/unsupported/taint.rb +16 -0
  245. data/spec/filters/unsupported/thread.rb +5 -0
  246. data/spec/filters/unsupported/time.rb +197 -16
  247. data/spec/lib/cli_spec.rb +14 -4
  248. data/spec/lib/compiler_spec.rb +9 -1
  249. data/spec/lib/parser/call_spec.rb +18 -0
  250. data/spec/lib/parser/not_spec.rb +2 -8
  251. data/spec/lib/sprockets_spec.rb +24 -0
  252. data/spec/opal/core/array/intersection_spec.rb +38 -0
  253. data/spec/opal/core/array/minus_spec.rb +38 -0
  254. data/spec/opal/core/array/union_spec.rb +38 -0
  255. data/spec/opal/core/array/uniq_spec.rb +49 -0
  256. data/spec/opal/core/exception_spec.rb +7 -0
  257. data/spec/opal/core/fixtures/require_tree_with_dot/file 1.rb +1 -0
  258. data/spec/opal/core/fixtures/require_tree_with_dot/file 2.rb +1 -0
  259. data/spec/opal/core/fixtures/require_tree_with_dot/file 3.rb +1 -0
  260. data/spec/opal/core/fixtures/require_tree_with_dot/index.rb +3 -0
  261. data/spec/opal/core/hash/internals_spec.rb +332 -0
  262. data/spec/opal/core/helpers_spec.rb +14 -0
  263. data/spec/opal/core/kernel/freeze_spec.rb +1 -1
  264. data/spec/opal/core/kernel/raise_spec.rb +13 -0
  265. data/spec/opal/core/kernel/require_tree_spec.rb +9 -0
  266. data/spec/opal/core/language/class_spec.rb +55 -0
  267. data/spec/opal/core/language/fixtures/send.rb +1 -0
  268. data/spec/opal/core/language/keyword_arguments_spec.rb +11 -0
  269. data/spec/opal/core/language/send_spec.rb +5 -0
  270. data/spec/opal/core/method/to_proc_spec.rb +28 -0
  271. data/spec/opal/core/module/name_spec.rb +0 -17
  272. data/spec/opal/core/runtime/bridged_classes_spec.rb +2 -2
  273. data/spec/opal/core/runtime/eval_spec.rb +1 -1
  274. data/spec/opal/core/runtime/method_missing_spec.rb +6 -0
  275. data/spec/opal/core/runtime_spec.rb +51 -0
  276. data/spec/opal/stdlib/js_spec.rb +66 -0
  277. data/spec/opal/stdlib/native/hash_spec.rb +36 -0
  278. data/spec/rubyspecs +152 -273
  279. data/spec/spec_helper.rb +10 -11
  280. data/stdlib/base64.rb +9 -9
  281. data/stdlib/benchmark.rb +551 -4
  282. data/stdlib/console.rb +94 -0
  283. data/stdlib/date.rb +1 -1
  284. data/stdlib/encoding.rb +1 -170
  285. data/stdlib/js.rb +56 -0
  286. data/stdlib/json.rb +9 -14
  287. data/stdlib/math.rb +1 -370
  288. data/stdlib/native.rb +133 -63
  289. data/stdlib/nodejs/file.rb +5 -0
  290. data/stdlib/nodejs/fileutils.rb +13 -6
  291. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/README.md +1 -1
  292. data/stdlib/opal-parser.rb +1 -2
  293. data/stdlib/ostruct.rb +65 -6
  294. data/stdlib/pp.rb +2 -4
  295. data/stdlib/rbconfig.rb +1 -3
  296. data/stdlib/strscan.rb +164 -28
  297. data/tasks/benchmarking.rake +88 -0
  298. data/tasks/testing.rake +181 -55
  299. data/{lib/mspec/opal/special_calls.rb → tasks/testing/mspec_special_calls.rb} +1 -1
  300. data/{lib/mspec/opal/sprockets.js → tasks/testing/phantomjs1-sprockets.js} +17 -6
  301. data/test/opal/test_keyword.rb +590 -0
  302. data/vendored-minitest/minitest.rb +2 -2
  303. data/vendored-minitest/test/unit.rb +5 -0
  304. metadata +229 -62
  305. data/benchmarks/operators.rb +0 -11
  306. data/benchmarks/prova.js.rb +0 -13
  307. data/docs/libraries.md +0 -36
  308. data/lib/mspec/opal/new.html.erb +0 -1
  309. data/lib/mspec/opal/rake_task.rb +0 -248
  310. data/opal/corelib/match_data.rb +0 -128
  311. data/spec/filters/bugs/math.rb +0 -95
  312. data/spec/filters/bugs/nil.rb +0 -7
  313. data/spec/filters/bugs/opal.rb +0 -9
  314. data/spec/filters/bugs/regular_expressions.rb +0 -41
  315. data/spec/filters/bugs/stringscanner.rb +0 -33
  316. data/spec/filters/unsupported/encoding.rb +0 -102
  317. data/spec/filters/unsupported/frozen.rb +0 -92
  318. data/spec/filters/unsupported/hash_compare_by_identity.rb +0 -16
  319. data/spec/filters/unsupported/integer_size.rb +0 -59
  320. data/spec/filters/unsupported/method_added.rb +0 -10
  321. data/spec/filters/unsupported/private_constants.rb +0 -30
  322. data/spec/filters/unsupported/private_methods.rb +0 -55
  323. data/spec/filters/unsupported/random.rb +0 -4
  324. data/spec/filters/unsupported/rational_numbers.rb +0 -4
  325. data/spec/filters/unsupported/regular_expressions.rb +0 -137
  326. data/spec/filters/unsupported/ruby_exe.rb +0 -5
  327. data/spec/filters/unsupported/symbols.rb +0 -17
  328. data/spec/filters/unsupported/tainted.rb +0 -180
  329. data/spec/filters/unsupported/trusted.rb +0 -88
  330. data/stdlib/process.rb +0 -10
  331. data/tasks/documenting.rake +0 -37
@@ -0,0 +1,9 @@
1
+ RUBY_PLATFORM = 'opal'
2
+ RUBY_ENGINE = 'opal'
3
+ RUBY_VERSION = '2.1.5'
4
+ RUBY_ENGINE_VERSION = '0.9.0.beta1'
5
+ RUBY_RELEASE_DATE = '2015-10-19'
6
+ RUBY_PATCHLEVEL = 0
7
+ RUBY_REVISION = 0
8
+ RUBY_COPYRIGHT = 'opal - Copyright (C) 2013-2015 Adam Beynon'
9
+ RUBY_DESCRIPTION = "opal #{RUBY_ENGINE_VERSION} (#{RUBY_RELEASE_DATE} revision #{RUBY_REVISION})"
@@ -67,12 +67,57 @@ module Enumerable
67
67
  }
68
68
  end
69
69
 
70
- def chunk(state = undefined, &block)
71
- raise NotImplementedError
70
+ def chunk(state = undefined, &original_block)
71
+ Kernel.raise ArgumentError, "no block given" unless original_block
72
+
73
+ ::Enumerator.new do |yielder|
74
+ %x{
75
+ var block, previous = nil, accumulate = [];
76
+
77
+ if (state == undefined || state === nil) {
78
+ block = original_block;
79
+ } else {
80
+ block = #{Proc.new { |val| original_block.yield(val, state.dup)}}
81
+ }
82
+
83
+ function releaseAccumulate() {
84
+ if (accumulate.length > 0) {
85
+ #{yielder.yield(`previous`, `accumulate`)}
86
+ }
87
+ }
88
+
89
+ self.$each.$$p = function(value) {
90
+ var key = Opal.yield1(block, value);
91
+
92
+ if (key === $breaker) {
93
+ return $breaker;
94
+ }
95
+
96
+ if (key === nil) {
97
+ releaseAccumulate();
98
+ accumulate = [];
99
+ previous = nil;
100
+ } else {
101
+ if (previous === nil || previous === key) {
102
+ accumulate.push(value);
103
+ } else {
104
+ releaseAccumulate();
105
+ accumulate = [value];
106
+ }
107
+
108
+ previous = key;
109
+ }
110
+ }
111
+
112
+ self.$each();
113
+
114
+ releaseAccumulate();
115
+ }
116
+ end
72
117
  end
73
118
 
74
119
  def collect(&block)
75
- return enum_for :collect unless block_given?
120
+ return enum_for(:collect){self.enumerator_size} unless block_given?
76
121
 
77
122
  %x{
78
123
  var result = [];
@@ -95,7 +140,7 @@ module Enumerable
95
140
  end
96
141
 
97
142
  def collect_concat(&block)
98
- return enum_for :collect_concat unless block_given?
143
+ return enum_for(:collect_concat){self.enumerator_size} unless block_given?
99
144
  map { |item| yield item }.flatten(1)
100
145
  end
101
146
 
@@ -132,7 +177,14 @@ module Enumerable
132
177
  end
133
178
 
134
179
  def cycle(n = nil, &block)
135
- return enum_for :cycle, n unless block
180
+ return enum_for(:cycle, n) {
181
+ if n == nil
182
+ respond_to?(:size) ? Float::INFINITY : nil
183
+ else
184
+ n = Opal.coerce_to!(n, Integer, :to_int)
185
+ n > 0 ? self.enumerator_size * n : 0
186
+ end
187
+ } unless block_given?
136
188
 
137
189
  unless n.nil?
138
190
  n = Opal.coerce_to! n, Integer, :to_int
@@ -142,7 +194,7 @@ module Enumerable
142
194
 
143
195
  %x{
144
196
  var result,
145
- all = [];
197
+ all = [], i, length, value;
146
198
 
147
199
  self.$each.$$p = function() {
148
200
  var param = #{Opal.destructure(`arguments`)},
@@ -165,13 +217,11 @@ module Enumerable
165
217
  if (all.length === 0) {
166
218
  return nil;
167
219
  }
168
- }
169
220
 
170
- if n.nil?
171
- %x{
221
+ if (n === nil) {
172
222
  while (true) {
173
- for (var i = 0, length = all.length; i < length; i++) {
174
- var value = Opal.yield1(block, all[i]);
223
+ for (i = 0, length = all.length; i < length; i++) {
224
+ value = Opal.yield1(block, all[i]);
175
225
 
176
226
  if (value === $breaker) {
177
227
  return $breaker.$v;
@@ -179,11 +229,10 @@ module Enumerable
179
229
  }
180
230
  }
181
231
  }
182
- else
183
- %x{
232
+ else {
184
233
  while (n > 1) {
185
- for (var i = 0, length = all.length; i < length; i++) {
186
- var value = Opal.yield1(block, all[i]);
234
+ for (i = 0, length = all.length; i < length; i++) {
235
+ value = Opal.yield1(block, all[i]);
187
236
 
188
237
  if (value === $breaker) {
189
238
  return $breaker.$v;
@@ -193,14 +242,14 @@ module Enumerable
193
242
  n--;
194
243
  }
195
244
  }
196
- end
245
+ }
197
246
  end
198
247
 
199
248
  def detect(ifnone = undefined, &block)
200
249
  return enum_for :detect, ifnone unless block_given?
201
250
 
202
251
  %x{
203
- var result = undefined;
252
+ var result;
204
253
 
205
254
  self.$each.$$p = function() {
206
255
  var params = #{Opal.destructure(`arguments`)},
@@ -306,7 +355,7 @@ module Enumerable
306
355
  raise ArgumentError, 'invalid slice size'
307
356
  end
308
357
 
309
- return enum_for :each_slice, n unless block_given?
358
+ return enum_for(:each_slice, n){respond_to?(:size) ? (size / n).ceil : nil} unless block_given?
310
359
 
311
360
  %x{
312
361
  var result,
@@ -345,7 +394,7 @@ module Enumerable
345
394
  end
346
395
 
347
396
  def each_with_index(*args, &block)
348
- return enum_for :each_with_index, *args unless block_given?
397
+ return enum_for(:each_with_index, *args){self.enumerator_size} unless block_given?
349
398
 
350
399
  %x{
351
400
  var result,
@@ -374,7 +423,7 @@ module Enumerable
374
423
  end
375
424
 
376
425
  def each_with_object(object, &block)
377
- return enum_for :each_with_object, object unless block_given?
426
+ return enum_for(:each_with_object, object){self.enumerator_size} unless block_given?
378
427
 
379
428
  %x{
380
429
  var result;
@@ -416,7 +465,7 @@ module Enumerable
416
465
  alias find detect
417
466
 
418
467
  def find_all(&block)
419
- return enum_for :find_all unless block_given?
468
+ return enum_for(:find_all){self.enumerator_size} unless block_given?
420
469
 
421
470
  %x{
422
471
  var result = [];
@@ -510,8 +559,8 @@ module Enumerable
510
559
  end
511
560
 
512
561
  %x{
513
- var current = 0,
514
- number = #{Opal.coerce_to number, Integer, :to_int};
562
+ var current = 0;
563
+ number = #{Opal.coerce_to number, Integer, :to_int};
515
564
 
516
565
  self.$each.$$p = function() {
517
566
  result.push(#{Opal.destructure(`arguments`)});
@@ -569,7 +618,7 @@ module Enumerable
569
618
  end
570
619
 
571
620
  def group_by(&block)
572
- return enum_for :group_by unless block_given?
621
+ return enum_for(:group_by){self.enumerator_size} unless block_given?
573
622
 
574
623
  hash = Hash.new
575
624
 
@@ -677,7 +726,6 @@ module Enumerable
677
726
  def enumerator_size
678
727
  respond_to?(:size) ? size : nil
679
728
  end
680
- private :enumerator_size
681
729
 
682
730
  alias map collect
683
731
 
@@ -732,7 +780,7 @@ module Enumerable
732
780
  end
733
781
 
734
782
  def max_by(&block)
735
- return enum_for :max_by unless block
783
+ return enum_for(:max_by){self.enumerator_size} unless block
736
784
 
737
785
  %x{
738
786
  var result,
@@ -818,7 +866,7 @@ module Enumerable
818
866
  end
819
867
 
820
868
  def min_by(&block)
821
- return enum_for :min_by unless block
869
+ return enum_for(:min_by){self.enumerator_size} unless block
822
870
 
823
871
  %x{
824
872
  var result,
@@ -940,7 +988,7 @@ module Enumerable
940
988
  end
941
989
 
942
990
  def partition(&block)
943
- return enum_for :partition unless block_given?
991
+ return enum_for(:partition){self.enumerator_size} unless block_given?
944
992
 
945
993
  %x{
946
994
  var truthy = [], falsy = [], result;
@@ -971,7 +1019,7 @@ module Enumerable
971
1019
  alias reduce inject
972
1020
 
973
1021
  def reject(&block)
974
- return enum_for :reject unless block_given?
1022
+ return enum_for(:reject){self.enumerator_size} unless block_given?
975
1023
 
976
1024
  %x{
977
1025
  var result = [];
@@ -997,7 +1045,7 @@ module Enumerable
997
1045
  end
998
1046
 
999
1047
  def reverse_each(&block)
1000
- return enum_for :reverse_each unless block_given?
1048
+ return enum_for(:reverse_each){self.enumerator_size} unless block_given?
1001
1049
 
1002
1050
  %x{
1003
1051
  var result = [];
@@ -1085,13 +1133,14 @@ module Enumerable
1085
1133
  end
1086
1134
 
1087
1135
  def sort_by(&block)
1088
- return enum_for :sort_by unless block_given?
1136
+ return enum_for(:sort_by){self.enumerator_size} unless block_given?
1089
1137
 
1090
- map {
1138
+ dup = map {
1091
1139
  arg = Opal.destructure(`arguments`)
1092
-
1093
1140
  [block.call(arg), arg]
1094
- }.sort { |a, b| a[0] <=> b[0] }.map { |arg| `arg[1]` }
1141
+ }
1142
+ dup.sort! { |a, b| `a[0]` <=> `b[0]` }
1143
+ dup.map! { |i| `i[1]` }
1095
1144
  end
1096
1145
 
1097
1146
  def take(num)
@@ -56,7 +56,7 @@ class Enumerator
56
56
  offset = 0
57
57
  end
58
58
 
59
- return enum_for :with_index, offset unless block
59
+ return enum_for(:with_index, offset){self.size} unless block
60
60
 
61
61
  %x{
62
62
  var result, index = offset;
@@ -71,6 +71,8 @@ class Enumerator
71
71
  }
72
72
 
73
73
  index++;
74
+
75
+ return value;
74
76
  }
75
77
 
76
78
  self.$each();
@@ -1,8 +1,7 @@
1
- class Exception
2
- attr_reader :message
3
-
4
- def self.new(message = 'Exception')
1
+ class Exception < `Error`
2
+ def self.new(*args)
5
3
  %x{
4
+ var message = (args.length > 0) ? args[0] : nil;
6
5
  var err = new self.$$alloc(message);
7
6
 
8
7
  if (Error.captureStackTrace) {
@@ -10,13 +9,18 @@ class Exception
10
9
  }
11
10
 
12
11
  err.name = self.$$name;
13
- err.$initialize(message);
12
+ err.$initialize.apply(err, args);
14
13
  return err;
15
14
  }
16
15
  end
16
+
17
+ def self.exception(*args)
18
+ new(*args)
19
+ end
17
20
 
18
- def initialize(message)
19
- `self.message = message`
21
+ def initialize(*args)
22
+ # using self.message aka @message to retain compatibility with native exception's message property
23
+ `self.message = (args.length > 0) ? args[0] : nil`
20
24
  end
21
25
 
22
26
  def backtrace
@@ -33,12 +37,33 @@ class Exception
33
37
  return [];
34
38
  }
35
39
  end
40
+
41
+ def exception(str=nil)
42
+ %x{
43
+ if (str === nil || self === str) {
44
+ return self;
45
+ }
46
+
47
+ var cloned = #{self.clone};
48
+ cloned.message = str;
49
+ return cloned;
50
+ }
51
+ end
52
+
53
+ # not using alias message to_s because you need to be able to override to_s and have message use overridden method, won't work with alias
54
+ def message
55
+ to_s
56
+ end
36
57
 
37
58
  def inspect
38
- "#<#{self.class}: '#@message'>"
59
+ as_str = to_s
60
+ as_str.empty? ? self.class.to_s : "#<#{self.class.to_s}: #{to_s}>"
61
+ end
62
+
63
+ def to_s
64
+ # using self.message aka @message to retain compatibility with native exception's message property
65
+ (@message && @message.to_s) || self.class.to_s
39
66
  end
40
-
41
- alias to_s message
42
67
  end
43
68
 
44
69
  # keep the indentation, it makes the exception hierarchy clear
@@ -51,8 +76,10 @@ class SystemExit < Exception; end
51
76
  class NoMemoryError < Exception; end
52
77
  class SignalException < Exception; end
53
78
  class Interrupt < Exception; end
79
+ class SecurityError < Exception; end
54
80
 
55
81
  class StandardError < Exception; end
82
+ class ZeroDivisionError < StandardError; end
56
83
  class NameError < StandardError; end
57
84
  class NoMethodError < NameError; end
58
85
  class RuntimeError < StandardError; end
@@ -66,6 +93,7 @@ class RangeError < StandardError; end
66
93
  class FloatDomainError < RangeError; end
67
94
  class IOError < StandardError; end
68
95
  class SystemCallError < StandardError; end
96
+
69
97
  module Errno
70
98
  class EINVAL < SystemCallError
71
99
  def self.new
@@ -73,3 +101,14 @@ module Errno
73
101
  end
74
102
  end
75
103
  end
104
+
105
+ class UncaughtThrowError < ArgumentError
106
+ attr_reader :sym, :arg
107
+
108
+ def initialize(args)
109
+ @sym = args[0]
110
+ @arg = args[1] if args.length > 1
111
+
112
+ super("uncaught throw #{@sym.inspect}")
113
+ end
114
+ end
data/opal/corelib/file.rb CHANGED
@@ -19,6 +19,7 @@ class File < IO
19
19
  end
20
20
  new_parts.join(SEPARATOR)
21
21
  end
22
+ alias realpath expand_path
22
23
 
23
24
  def dirname(path)
24
25
  split(path)[0..-2]
data/opal/corelib/hash.rb CHANGED
@@ -8,7 +8,7 @@ class Hash
8
8
 
9
9
  def self.[](*argv)
10
10
  %x{
11
- var hash, i, argc = argv.length;
11
+ var hash, argc = argv.length, i;
12
12
 
13
13
  if (argc === 1) {
14
14
  hash = #{Opal.coerce_to?(argv[0], Hash, :to_hash)};
@@ -57,11 +57,10 @@ class Hash
57
57
 
58
58
  def self.allocate
59
59
  %x{
60
- var hash = new self.$$alloc;
60
+ var hash = new self.$$alloc();
61
+
62
+ Opal.hash_init(hash);
61
63
 
62
- hash.map = {};
63
- hash.smap = {};
64
- hash.keys = [];
65
64
  hash.none = nil;
66
65
  hash.proc = nil;
67
66
 
@@ -69,8 +68,15 @@ class Hash
69
68
  }
70
69
  end
71
70
 
71
+ def self.try_convert(obj)
72
+ Opal.coerce_to?(obj, Hash, :to_hash)
73
+ end
74
+
72
75
  def initialize(defaults = undefined, &block)
73
76
  %x{
77
+ if (defaults !== undefined && block !== nil) {
78
+ #{raise ArgumentError, 'wrong number of arguments (1 for 0)'}
79
+ }
74
80
  self.none = (defaults === undefined ? nil : defaults);
75
81
  self.proc = block;
76
82
  }
@@ -83,7 +89,7 @@ class Hash
83
89
  return true;
84
90
  }
85
91
 
86
- if (!other.keys || !other.smap || !other.map) {
92
+ if (!other.$$is_hash) {
87
93
  return false;
88
94
  }
89
95
 
@@ -91,30 +97,18 @@ class Hash
91
97
  return false;
92
98
  }
93
99
 
94
- var _map = self.map,
95
- smap = self.smap,
96
- _map2 = other.map,
97
- smap2 = other.smap,
98
- map, map2, key, khash, value, value2;
99
-
100
- for (var i = 0, length = self.keys.length; i < length; i++) {
101
- key = self.keys[i];
100
+ for (var i = 0, keys = self.keys, length = keys.length, key, value, other_value; i < length; i++) {
101
+ key = keys[i];
102
102
 
103
103
  if (key.$$is_string) {
104
- khash = key;
105
- map = smap;
106
- map2 = smap2;
104
+ value = self.smap[key];
105
+ other_value = other.smap[key];
107
106
  } else {
108
- khash = key.$hash();
109
- map = _map;
110
- map2 = _map2;
107
+ value = key.value;
108
+ other_value = Opal.hash_get(other, key.key);
111
109
  }
112
110
 
113
- value = map[khash];
114
- if (value === undefined) console.log('==', key, self);
115
- value2 = map2[khash];
116
-
117
- if (value2 === undefined || #{not(`value` == `value2`)}) {
111
+ if (other_value === undefined || !value['$eql?'](other_value)) {
118
112
  return false;
119
113
  }
120
114
  }
@@ -125,73 +119,36 @@ class Hash
125
119
 
126
120
  def [](key)
127
121
  %x{
128
- var map, khash;
129
-
130
- if (key.$$is_string) {
131
- map = self.smap;
132
- khash = key;
133
- } else {
134
- map = self.map;
135
- khash = key.$hash();
136
- }
137
-
138
- if (map === undefined) { console.log(self, '[] --> key:', key, khash, map) }
139
-
140
-
141
- if (Opal.hasOwnProperty.call(map, khash)) {
142
- return map[khash];
143
- }
144
-
145
- var proc = #@proc;
122
+ var value = Opal.hash_get(self, key);
146
123
 
147
- if (proc !== nil) {
148
- return #{ `proc`.call self, key };
124
+ if (value !== undefined) {
125
+ return value;
149
126
  }
150
127
 
151
- return #@none;
128
+ return self.$default(key);
152
129
  }
153
130
  end
154
131
 
155
132
  def []=(key, value)
156
133
  %x{
157
- var map, khash, value;
158
-
159
- if (key.$$is_string) {
160
- map = self.smap;
161
- khash = key;
162
- } else {
163
- map = self.map;
164
- khash = key.$hash();
165
- }
166
-
167
- if (!Opal.hasOwnProperty.call(map, khash)) {
168
- self.keys.push(key);
169
- }
170
-
171
- map[khash] = value;
172
-
134
+ Opal.hash_put(self, key, value);
173
135
  return value;
174
136
  }
175
137
  end
176
138
 
177
139
  def assoc(object)
178
140
  %x{
179
- var keys = self.keys,
180
- map, key, khash;
181
-
182
- for (var i = 0, length = keys.length; i < length; i++) {
141
+ for (var i = 0, keys = self.keys, length = keys.length, key; i < length; i++) {
183
142
  key = keys[i];
184
143
 
185
- if (#{`key` == object}) {
186
- if (key.$$is_string) {
187
- map = self.smap;
188
- khash = key;
189
- } else {
190
- map = self.map;
191
- khash = key.$hash();
144
+ if (key.$$is_string) {
145
+ if (#{`key` == object}) {
146
+ return [key, self.smap[key]];
147
+ }
148
+ } else {
149
+ if (#{`key.key` == object}) {
150
+ return [key.key, key.value];
192
151
  }
193
-
194
- return [key, map[khash]];
195
152
  }
196
153
  }
197
154
 
@@ -201,66 +158,37 @@ class Hash
201
158
 
202
159
  def clear
203
160
  %x{
204
- self.map = {};
205
- self.smap = {};
206
- self.keys = [];
161
+ Opal.hash_init(self);
207
162
  return self;
208
163
  }
209
164
  end
210
165
 
211
166
  def clone
212
167
  %x{
213
- var _map = {},
214
- smap = {},
215
- _map2 = self.map,
216
- smap2 = self.smap,
217
- keys = [],
218
- map, map2, key, khash, value;
219
-
220
- for (var i = 0, length = self.keys.length; i < length; i++) {
221
- key = self.keys[i];
168
+ var hash = new self.$$class.$$alloc();
222
169
 
223
- if (key.$$is_string) {
224
- khash = key;
225
- map = smap;
226
- map2 = smap2;
227
- } else {
228
- khash = key.$hash();
229
- map = _map;
230
- map2 = _map2;
231
- }
170
+ Opal.hash_init(hash);
171
+ Opal.hash_clone(self, hash);
232
172
 
233
- value = map2[khash];
234
-
235
- keys.push(key);
236
- map[khash] = value;
237
- }
238
-
239
- var clone = new self.$$class.$$alloc();
240
-
241
- clone.map = _map;
242
- clone.smap = smap;
243
- clone.keys = keys;
244
- clone.none = self.none;
245
- clone.proc = self.proc;
246
-
247
- return clone;
173
+ return hash;
248
174
  }
249
175
  end
250
176
 
251
- def default(val = undefined)
177
+ def default(key = undefined)
252
178
  %x{
253
- if (val !== undefined && self.proc !== nil) {
254
- return #{@proc.call(self, val)};
179
+ if (key !== undefined && #@proc !== nil) {
180
+ return #@proc.$call(self, key);
255
181
  }
256
- return self.none;
182
+ return #@none;
257
183
  }
258
184
  end
259
185
 
260
186
  def default=(object)
261
187
  %x{
262
188
  self.proc = nil;
263
- return (self.none = object);
189
+ self.none = object;
190
+
191
+ return object;
264
192
  }
265
193
  end
266
194
 
@@ -273,75 +201,59 @@ class Hash
273
201
  if (proc !== nil) {
274
202
  proc = #{Opal.coerce_to!(proc, Proc, :to_proc)};
275
203
 
276
- if (#{proc.lambda?} && #{proc.arity.abs} != 2) {
277
- #{raise TypeError, "default_proc takes two arguments"};
204
+ if (#{proc.lambda?} && #{proc.arity.abs} !== 2) {
205
+ #{raise TypeError, 'default_proc takes two arguments'};
278
206
  }
279
207
  }
208
+
280
209
  self.none = nil;
281
- return (self.proc = proc);
210
+ self.proc = proc;
211
+
212
+ return proc;
282
213
  }
283
214
  end
284
215
 
285
216
  def delete(key, &block)
286
217
  %x{
287
- var result, map, khash;
288
-
289
- if (key.$$is_string) {
290
- map = self.smap;
291
- khash = key;
292
- } else {
293
- map = self.map;
294
- khash = key.$hash();
295
- }
296
-
297
- result = map[khash];
218
+ var value = Opal.hash_delete(self, key);
298
219
 
299
- if (result != null) {
300
- delete map[khash];
301
- self.keys.$delete(key);
302
-
303
- return result;
220
+ if (value !== undefined) {
221
+ return value;
304
222
  }
305
223
 
306
224
  if (block !== nil) {
307
225
  return #{block.call(key)};
308
226
  }
227
+
309
228
  return nil;
310
229
  }
311
230
  end
312
231
 
313
232
  def delete_if(&block)
314
- return enum_for :delete_if unless block
233
+ return enum_for(:delete_if){self.size} unless block
315
234
 
316
235
  %x{
317
- var _map = self.map,
318
- smap = self.smap,
319
- keys = self.keys,
320
- map, key, value, obj, khash;
321
-
322
- for (var i = 0, length = keys.length; i < length; i++) {
236
+ for (var i = 0, keys = self.keys, length = keys.length, key, value, obj; i < length; i++) {
323
237
  key = keys[i];
324
238
 
325
239
  if (key.$$is_string) {
326
- map = smap;
327
- khash = key;
240
+ value = self.smap[key];
328
241
  } else {
329
- map = _map;
330
- khash = key.$hash();
242
+ value = key.value;
243
+ key = key.key;
331
244
  }
332
- obj = map[khash];
333
- value = block(key, obj);
334
245
 
335
- if (value === $breaker) {
246
+ obj = block(key, value);
247
+
248
+ if (obj === $breaker) {
336
249
  return $breaker.$v;
337
250
  }
338
251
 
339
- if (value !== false && value !== nil) {
340
- keys.splice(i, 1);
341
- delete map[khash];
342
-
343
- length--;
344
- i--;
252
+ if (obj !== false && obj !== nil) {
253
+ if (Opal.hash_delete(self, key) !== undefined) {
254
+ length--;
255
+ i--;
256
+ }
345
257
  }
346
258
  }
347
259
 
@@ -352,28 +264,22 @@ class Hash
352
264
  alias dup clone
353
265
 
354
266
  def each(&block)
355
- return enum_for :each unless block
267
+ return enum_for(:each){self.size} unless block
356
268
 
357
269
  %x{
358
- var _map = self.map,
359
- smap = self.smap,
360
- keys = self.keys,
361
- map, key, khash, value;
362
-
363
- for (var i = 0, length = keys.length; i < length; i++) {
270
+ for (var i = 0, keys = self.keys, length = keys.length, key, value, obj; i < length; i++) {
364
271
  key = keys[i];
365
272
 
366
273
  if (key.$$is_string) {
367
- map = smap;
368
- khash = key;
274
+ value = self.smap[key];
369
275
  } else {
370
- map = _map;
371
- khash = key.$hash();
276
+ value = key.value;
277
+ key = key.key;
372
278
  }
373
279
 
374
- value = Opal.yield1(block, [key, map[khash]]);
280
+ obj = Opal.yield1(block, [key, value]);
375
281
 
376
- if (value === $breaker) {
282
+ if (obj === $breaker) {
377
283
  return $breaker.$v;
378
284
  }
379
285
  }
@@ -383,15 +289,13 @@ class Hash
383
289
  end
384
290
 
385
291
  def each_key(&block)
386
- return enum_for :each_key unless block
387
- # @keys.each(&block)
388
- %x{
389
- var keys = self.keys, key;
292
+ return enum_for(:each_key){self.size} unless block
390
293
 
391
- for (var i = 0, length = keys.length; i < length; i++) {
294
+ %x{
295
+ for (var i = 0, keys = self.keys, length = keys.length, key; i < length; i++) {
392
296
  key = keys[i];
393
297
 
394
- if (block(key) === $breaker) {
298
+ if (block(key.$$is_string ? key : key.key) === $breaker) {
395
299
  return $breaker.$v;
396
300
  }
397
301
  }
@@ -403,25 +307,13 @@ class Hash
403
307
  alias each_pair each
404
308
 
405
309
  def each_value(&block)
406
- return enum_for :each_value unless block
310
+ return enum_for(:each_value){self.size} unless block
407
311
 
408
312
  %x{
409
- var _map = self.map,
410
- smap = self.smap,
411
- keys = self.keys, key, map, khash;
412
-
413
- for (var i = 0, length = keys.length; i < length; i++) {
313
+ for (var i = 0, keys = self.keys, length = keys.length, key; i < length; i++) {
414
314
  key = keys[i];
415
315
 
416
- if (key.$$is_string) {
417
- map = smap;
418
- khash = key;
419
- } else {
420
- map = _map;
421
- khash = key.$hash();
422
- }
423
-
424
- if (block(map[khash]) === $breaker) {
316
+ if (block(key.$$is_string ? self.smap[key] : key.value) === $breaker) {
425
317
  return $breaker.$v;
426
318
  }
427
319
  }
@@ -438,74 +330,59 @@ class Hash
438
330
 
439
331
  def fetch(key, defaults = undefined, &block)
440
332
  %x{
441
- var map, khash, value;
442
-
443
- if (key.$$is_string) {
444
- khash = key;
445
- map = self.smap;
446
- } else {
447
- khash = key.$hash();
448
- map = self.map;
449
- }
450
-
451
- value = map[khash];
333
+ var value = Opal.hash_get(self, key);
452
334
 
453
- if (value != null) {
335
+ if (value !== undefined) {
454
336
  return value;
455
337
  }
456
338
 
457
339
  if (block !== nil) {
458
- var value;
340
+ value = block(key);
459
341
 
460
- if ((value = block(key)) === $breaker) {
342
+ if (value === $breaker) {
461
343
  return $breaker.$v;
462
344
  }
463
345
 
464
346
  return value;
465
347
  }
466
348
 
467
- if (defaults != null) {
349
+ if (defaults !== undefined) {
468
350
  return defaults;
469
351
  }
470
-
471
- #{ raise KeyError, "key not found: #{key.inspect}" };
472
352
  }
353
+
354
+ raise KeyError, "key not found: #{key.inspect}"
473
355
  end
474
356
 
475
- def flatten(level=undefined)
357
+ def flatten(level = 1)
358
+ level = Opal.coerce_to!(level, Integer, :to_int)
359
+
476
360
  %x{
477
- var _map = self.map,
478
- smap = self.smap,
479
- keys = self.keys,
480
- result = [],
481
- map, key, khash, value;
361
+ var result = [];
482
362
 
483
- for (var i = 0, length = keys.length; i < length; i++) {
363
+ for (var i = 0, keys = self.keys, length = keys.length, key, value; i < length; i++) {
484
364
  key = keys[i];
485
365
 
486
366
  if (key.$$is_string) {
487
- khash = key;
488
- map = smap;
367
+ value = self.smap[key];
489
368
  } else {
490
- khash = key.$hash();
491
- map = _map;
369
+ value = key.value;
370
+ key = key.key;
492
371
  }
493
372
 
494
- value = map[khash];
495
-
496
373
  result.push(key);
497
374
 
498
375
  if (value.$$is_array) {
499
- if (level == null || level === 1) {
376
+ if (level === 1) {
500
377
  result.push(value);
378
+ continue;
501
379
  }
502
- else {
503
- result = result.concat(#{`value`.flatten(`level - 1`)});
504
- }
505
- }
506
- else {
507
- result.push(value);
380
+
381
+ result = result.concat(#{`value`.flatten(`level - 2`)});
382
+ continue;
508
383
  }
384
+
385
+ result.push(value);
509
386
  }
510
387
 
511
388
  return result;
@@ -513,48 +390,15 @@ class Hash
513
390
  end
514
391
 
515
392
  def has_key?(key)
516
- %x{
517
- var keys = self.keys,
518
- map, khash;
519
-
520
- if (key.$$is_string) {
521
- khash = key;
522
- map = self.smap;
523
- } else {
524
- khash = key.$hash();
525
- map = self.map;
526
- }
527
-
528
- if (Opal.hasOwnProperty.call(map, khash)) {
529
- for (var i = 0, length = keys.length; i < length; i++) {
530
- if (!#{not(key.eql?(`keys[i]`))}) {
531
- return true;
532
- }
533
- }
534
- }
535
-
536
- return false;
537
- }
393
+ `Opal.hash_get(self, key) !== undefined`
538
394
  end
539
395
 
540
396
  def has_value?(value)
541
397
  %x{
542
- var _map = self.map,
543
- smap = self.smap,
544
- keys = self.keys, key, map, khash;
545
-
546
- for (var i = 0, length = keys.length; i < length; i++) {
398
+ for (var i = 0, keys = self.keys, length = keys.length, key; i < length; i++) {
547
399
  key = keys[i];
548
400
 
549
- if (key.$$is_string) {
550
- map = smap;
551
- khash = key;
552
- } else {
553
- map = _map;
554
- khash = key.$hash();
555
- }
556
-
557
- if (#{`map[khash]` == value}) {
401
+ if (#{`(key.$$is_string ? self.smap[key] : key.value)` == value}) {
558
402
  return true;
559
403
  }
560
404
  }
@@ -563,39 +407,48 @@ class Hash
563
407
  }
564
408
  end
565
409
 
566
- `var hash_ids = null;`
567
410
  def hash
568
411
  %x{
569
- var top = (hash_ids === null);
570
- try {
571
- var key, value,
572
- hash = ['Hash'],
573
- keys = self.keys,
574
- id = self.$object_id(),
575
- counter = 0;
412
+ var top = (Opal.hash_ids === undefined),
413
+ hash_id = self.$object_id(),
414
+ result = ['Hash'],
415
+ key, item;
576
416
 
417
+ try {
577
418
  if (top) {
578
- hash_ids = {}
419
+ Opal.hash_ids = {};
579
420
  }
580
421
 
581
- if (hash_ids.hasOwnProperty(id)) {
422
+ if (Opal.hash_ids.hasOwnProperty(hash_id)) {
582
423
  return 'self';
583
424
  }
584
425
 
585
- hash_ids[id] = true;
426
+ for (key in Opal.hash_ids) {
427
+ if (Opal.hash_ids.hasOwnProperty(key)) {
428
+ item = Opal.hash_ids[key];
429
+ if (#{eql?(`item`)}) {
430
+ return 'self';
431
+ }
432
+ }
433
+ }
434
+
435
+ Opal.hash_ids[hash_id] = self;
586
436
 
587
- for (var i = 0, length = keys.length; i < length; i++) {
588
- key = keys[i];
589
- value = key.$$is_string ? self.smap[key] : self.map[key.$hash()];
590
- key = key.$hash();
591
- value = (typeof(value) === 'undefined') ? '' : value.$hash();
592
- hash.push([key,value]);
437
+ for (var i = 0, keys = self.keys, length = keys.length; i < length; i++) {
438
+ key = keys[i];
439
+
440
+ if (key.$$is_string) {
441
+ result.push([key, self.smap[key].$hash()]);
442
+ } else {
443
+ result.push([key.key_hash, key.value.$hash()]);
444
+ }
593
445
  }
594
446
 
595
- return hash.sort().join();
447
+ return result.sort().join();
448
+
596
449
  } finally {
597
450
  if (top) {
598
- hash_ids = null;
451
+ delete Opal.hash_ids;
599
452
  }
600
453
  }
601
454
  }
@@ -605,23 +458,17 @@ class Hash
605
458
 
606
459
  def index(object)
607
460
  %x{
608
- var _map = self.map,
609
- smap = self.smap,
610
- keys = self.keys,
611
- map, khash, key;
612
-
613
- for (var i = 0, length = keys.length; i < length; i++) {
461
+ for (var i = 0, keys = self.keys, length = keys.length, key, value; i < length; i++) {
614
462
  key = keys[i];
615
463
 
616
464
  if (key.$$is_string) {
617
- map = smap;
618
- khash = key;
465
+ value = self.smap[key];
619
466
  } else {
620
- map = _map;
621
- khash = key.$hash();
467
+ value = key.value;
468
+ key = key.key;
622
469
  }
623
470
 
624
- if (#{`map[khash]` == object}) {
471
+ if (#{`value` == object}) {
625
472
  return key;
626
473
  }
627
474
  }
@@ -630,32 +477,20 @@ class Hash
630
477
  }
631
478
  end
632
479
 
633
- def indexes(*keys)
480
+ def indexes(*args)
634
481
  %x{
635
- var result = [],
636
- _map = self.map,
637
- smap = self.smap,
638
- map, key, khash, value;
482
+ var result = [];
639
483
 
640
- for (var i = 0, length = keys.length; i < length; i++) {
641
- key = keys[i];
484
+ for (var i = 0, length = args.length, key, value; i < length; i++) {
485
+ key = args[i];
486
+ value = Opal.hash_get(self, key);
642
487
 
643
- if (key.$$is_string) {
644
- khash = key;
645
- map = smap;
646
- } else {
647
- khash = key.$hash();
648
- map = _map;
488
+ if (value === undefined) {
489
+ result.push(#{default});
490
+ continue;
649
491
  }
650
492
 
651
- value = map[khash];
652
-
653
- if (value != null) {
654
- result.push(value);
655
- }
656
- else {
657
- result.push(self.none);
658
- }
493
+ result.push(value);
659
494
  }
660
495
 
661
496
  return result;
@@ -664,41 +499,43 @@ class Hash
664
499
 
665
500
  alias indices indexes
666
501
 
667
- `var inspect_ids = null;`
502
+ `var inspect_ids;`
503
+
668
504
  def inspect
669
505
  %x{
670
- var top = (inspect_ids === null);
671
- try {
672
-
673
- var key, value,
674
- inspect = [],
675
- keys = self.keys,
676
- id = self.$object_id(),
677
- counter = 0;
506
+ var top = (inspect_ids === undefined),
507
+ hash_id = self.$object_id(),
508
+ result = [];
678
509
 
510
+ try {
679
511
  if (top) {
680
- inspect_ids = {}
512
+ inspect_ids = {};
681
513
  }
682
514
 
683
- if (inspect_ids.hasOwnProperty(id)) {
515
+ if (inspect_ids.hasOwnProperty(hash_id)) {
684
516
  return '{...}';
685
517
  }
686
518
 
687
- inspect_ids[id] = true;
519
+ inspect_ids[hash_id] = true;
520
+
521
+ for (var i = 0, keys = self.keys, length = keys.length, key, value; i < length; i++) {
522
+ key = keys[i];
523
+
524
+ if (key.$$is_string) {
525
+ value = self.smap[key];
526
+ } else {
527
+ value = key.value;
528
+ key = key.key;
529
+ }
688
530
 
689
- for (var i = 0, length = keys.length; i < length; i++) {
690
- key = keys[i];
691
- value = key.$$is_string ? self.smap[key] : self.map[key.$hash()];
692
- key = key.$inspect();
693
- value = value.$inspect();
694
- inspect.push(key + '=>' + value);
531
+ result.push(key.$inspect() + '=>' + value.$inspect());
695
532
  }
696
533
 
697
- return '{' + inspect.join(', ') + '}';
698
- } finally {
534
+ return '{' + result.join(', ') + '}';
699
535
 
536
+ } finally {
700
537
  if (top) {
701
- inspect_ids = null;
538
+ inspect_ids = undefined;
702
539
  }
703
540
  }
704
541
  }
@@ -706,77 +543,50 @@ class Hash
706
543
 
707
544
  def invert
708
545
  %x{
709
- var result = Opal.hash(),
710
- keys = self.keys,
711
- _map = self.map,
712
- smap = self.smap,
713
- keys2 = result.keys,
714
- _map2 = result.map,
715
- smap2 = result.smap,
716
- map, map2, key, khash, value;
717
-
718
- for (var i = 0, length = keys.length; i < length; i++) {
546
+ var hash = Opal.hash();
547
+
548
+ for (var i = 0, keys = self.keys, length = keys.length, key, value; i < length; i++) {
719
549
  key = keys[i];
720
550
 
721
551
  if (key.$$is_string) {
722
- map = smap;
723
- khash = key;
724
- } else {
725
- map = _map;
726
- khash = key.$hash();
727
- }
728
-
729
- value = map[khash];
730
- keys2.push(value);
731
-
732
- if (value.$$is_string) {
733
- map2 = smap2;
734
- khash = value;
552
+ value = self.smap[key];
735
553
  } else {
736
- map2 = _map2;
737
- khash = value.$hash();
554
+ value = key.value;
555
+ key = key.key;
738
556
  }
739
557
 
740
- map2[khash] = key;
558
+ Opal.hash_put(hash, value, key);
741
559
  }
742
560
 
743
- return result;
561
+ return hash;
744
562
  }
745
563
  end
746
564
 
747
565
  def keep_if(&block)
748
- return enum_for :keep_if unless block
566
+ return enum_for(:keep_if){self.size} unless block
749
567
 
750
568
  %x{
751
- var _map = self.map,
752
- smap = self.smap,
753
- keys = self.keys,
754
- map, key, khash, value, keep;
755
-
756
- for (var i = 0, length = keys.length; i < length; i++) {
569
+ for (var i = 0, keys = self.keys, length = keys.length, key, value, obj; i < length; i++) {
757
570
  key = keys[i];
758
571
 
759
572
  if (key.$$is_string) {
760
- khash = key;
761
- map = smap;
573
+ value = self.smap[key];
762
574
  } else {
763
- khash = key.$hash();
764
- map = _map;
575
+ value = key.value;
576
+ key = key.key;
765
577
  }
766
578
 
767
- value = map[khash];
768
- keep = block(key, value);
579
+ obj = block(key, value);
769
580
 
770
- if (keep === $breaker) {
581
+ if (obj === $breaker) {
771
582
  return $breaker.$v;
772
583
  }
773
584
 
774
- if (keep === false || keep === nil) {
775
- keys.splice(i, 1);
776
- delete map[khash];
777
-
778
- length--;
779
- i--;
585
+ if (obj === false || obj === nil) {
586
+ if (Opal.hash_delete(self, key) !== undefined) {
587
+ length--;
588
+ i--;
589
+ }
780
590
  }
781
591
  }
782
592
 
@@ -789,7 +599,21 @@ class Hash
789
599
  alias key? has_key?
790
600
 
791
601
  def keys
792
- `self.keys.slice(0)`
602
+ %x{
603
+ var result = [];
604
+
605
+ for (var i = 0, keys = self.keys, length = keys.length, key; i < length; i++) {
606
+ key = keys[i];
607
+
608
+ if (key.$$is_string) {
609
+ result.push(key);
610
+ } else {
611
+ result.push(key.key);
612
+ }
613
+ }
614
+
615
+ return result;
616
+ }
793
617
  end
794
618
 
795
619
  def length
@@ -799,75 +623,52 @@ class Hash
799
623
  alias member? has_key?
800
624
 
801
625
  def merge(other, &block)
802
- unless Hash === other
803
- other = Opal.coerce_to!(other, Hash, :to_hash)
804
- end
805
-
806
- cloned = clone
807
- cloned.merge!(other, &block)
808
- cloned
626
+ dup.merge!(other, &block)
809
627
  end
810
628
 
811
629
  def merge!(other, &block)
812
630
  %x{
813
- if (! #{Hash === other}) {
631
+ if (!#{Hash === other}) {
814
632
  other = #{Opal.coerce_to!(other, Hash, :to_hash)};
815
633
  }
816
634
 
817
- var keys = self.keys,
818
- _map = self.map,
819
- smap = self.smap,
820
- keys2 = other.keys,
821
- _map2 = other.map,
822
- smap2 = other.smap,
823
- map, map2, key, khash, value, value2;
635
+ var i, other_keys = other.keys, length = other_keys.length, key, value, other_value;
824
636
 
825
637
  if (block === nil) {
826
- for (var i = 0, length = keys2.length; i < length; i++) {
827
- key = keys2[i];
638
+ for (i = 0; i < length; i++) {
639
+ key = other_keys[i];
828
640
 
829
641
  if (key.$$is_string) {
830
- khash = key;
831
- map = smap;
832
- map2 = smap2;
642
+ other_value = other.smap[key];
833
643
  } else {
834
- khash = key.$hash();
835
- map = _map;
836
- map2 = _map2;
644
+ other_value = key.value;
645
+ key = key.key;
837
646
  }
838
647
 
839
- if (map[khash] == null) {
840
- keys.push(key);
841
- }
842
-
843
- map[khash] = map2[khash];
648
+ Opal.hash_put(self, key, other_value);
844
649
  }
650
+
651
+ return self;
845
652
  }
846
- else {
847
- for (var i = 0, length = keys2.length; i < length; i++) {
848
- key = keys2[i];
849
653
 
850
- if (key.$$is_string) {
851
- khash = key;
852
- map = smap;
853
- map2 = smap2;
854
- } else {
855
- khash = key.$hash();
856
- map = _map;
857
- map2 = _map2;
858
- }
654
+ for (i = 0; i < length; i++) {
655
+ key = other_keys[i];
656
+
657
+ if (key.$$is_string) {
658
+ other_value = other.smap[key];
659
+ } else {
660
+ other_value = key.value;
661
+ key = key.key;
662
+ }
859
663
 
860
- value = map[khash];
861
- value2 = map2[khash];
664
+ value = Opal.hash_get(self, key);
862
665
 
863
- if (value == null) {
864
- keys.push(key);
865
- map[khash] = value2;
866
- }
867
- else {
868
- map[khash] = block(key, value, value2);
869
- }
666
+ if (value === undefined) {
667
+ Opal.hash_put(self, key, other_value);
668
+ continue;
870
669
  }
670
+
671
+ Opal.hash_put(self, key, block(key, value, other_value));
871
672
  }
872
673
 
873
674
  return self;
@@ -876,24 +677,16 @@ class Hash
876
677
 
877
678
  def rassoc(object)
878
679
  %x{
879
- var keys = self.keys,
880
- _map = self.map,
881
- smap = self.smap,
882
- key, khash, value, map;
883
-
884
- for (var i = 0, length = keys.length; i < length; i++) {
885
- key = keys[i]
680
+ for (var i = 0, keys = self.keys, length = keys.length, key, value; i < length; i++) {
681
+ key = keys[i];
886
682
 
887
683
  if (key.$$is_string) {
888
- khash = key;
889
- map = smap;
684
+ value = self.smap[key];
890
685
  } else {
891
- khash = key.$hash();
892
- map = _map;
686
+ value = key.value;
687
+ key = key.key;
893
688
  }
894
689
 
895
- value = map[khash];
896
-
897
690
  if (#{`value` == object}) {
898
691
  return [key, value];
899
692
  }
@@ -903,156 +696,167 @@ class Hash
903
696
  }
904
697
  end
905
698
 
699
+ def rehash
700
+ %x{
701
+ Opal.hash_rehash(self);
702
+ return self;
703
+ }
704
+ end
705
+
906
706
  def reject(&block)
907
- return enum_for :reject unless block
707
+ return enum_for(:reject){self.size} unless block
908
708
 
909
709
  %x{
910
- var keys = self.keys,
911
- _map = self.map,
912
- smap = self.smap,
913
- result = Opal.hash(),
914
- _map2 = result.map,
915
- smap2 = result.smap,
916
- keys2 = result.keys,
917
- map, map2, key, khash, object, value;
918
-
919
- for (var i = 0, length = keys.length; i < length; i++) {
710
+ var hash = Opal.hash();
711
+
712
+ for (var i = 0, keys = self.keys, length = keys.length, key, value, obj; i < length; i++) {
920
713
  key = keys[i];
921
714
 
922
715
  if (key.$$is_string) {
923
- khash = key;
924
- map = smap;
925
- map2 = smap2;
716
+ value = self.smap[key];
926
717
  } else {
927
- khash = key.$hash();
928
- map = _map;
929
- map2 = _map2;
718
+ value = key.value;
719
+ key = key.key;
930
720
  }
931
721
 
932
- object = map[khash];
722
+ obj = block(key, value);
933
723
 
934
- if ((value = block(key, object)) === $breaker) {
724
+ if (obj === $breaker) {
935
725
  return $breaker.$v;
936
726
  }
937
727
 
938
- if (value === false || value === nil) {
939
- keys2.push(key);
940
- map2[khash] = object;
728
+ if (obj === false || obj === nil) {
729
+ Opal.hash_put(hash, key, value);
941
730
  }
942
731
  }
943
732
 
944
- return result;
733
+ return hash;
945
734
  }
946
735
  end
947
736
 
948
- def replace(other)
737
+ def reject!(&block)
738
+ return enum_for(:reject!){self.size} unless block
739
+
949
740
  %x{
950
- var keys = self.keys = [],
951
- _map = self.map = {},
952
- smap = self.smap = {},
953
- _map2 = other.map,
954
- smap2 = other.smap,
955
- key, khash, map, map2;
741
+ var changes_were_made = false;
956
742
 
957
- for (var i = 0, length = other.keys.length; i < length; i++) {
958
- key = other.keys[i];
743
+ for (var i = 0, keys = self.keys, length = keys.length, key, value, obj; i < length; i++) {
744
+ key = keys[i];
959
745
 
960
746
  if (key.$$is_string) {
961
- khash = key;
962
- map = smap;
963
- map2 = smap2;
747
+ value = self.smap[key];
964
748
  } else {
965
- khash = key.$hash();
966
- map = _map;
967
- map2 = _map2;
749
+ value = key.value;
750
+ key = key.key;
751
+ }
752
+
753
+ obj = block(key, value);
754
+
755
+ if (obj === $breaker) {
756
+ return $breaker.$v;
968
757
  }
969
758
 
970
- keys.push(key);
971
- map[khash] = map2[khash];
759
+ if (obj !== false && obj !== nil) {
760
+ if (Opal.hash_delete(self, key) !== undefined) {
761
+ changes_were_made = true;
762
+ length--;
763
+ i--;
764
+ }
765
+ }
972
766
  }
973
767
 
974
- return self;
768
+ return changes_were_made ? self : nil;
769
+ }
770
+ end
771
+
772
+ def replace(other)
773
+ other = Opal.coerce_to!(other, Hash, :to_hash)
774
+
775
+ %x{
776
+ Opal.hash_init(self);
777
+
778
+ for (var i = 0, other_keys = other.keys, length = other_keys.length, key, value, other_value; i < length; i++) {
779
+ key = other_keys[i];
780
+
781
+ if (key.$$is_string) {
782
+ other_value = other.smap[key];
783
+ } else {
784
+ other_value = key.value;
785
+ key = key.key;
786
+ }
787
+
788
+ Opal.hash_put(self, key, other_value);
789
+ }
975
790
  }
791
+
792
+ if other.default_proc
793
+ self.default_proc = other.default_proc
794
+ else
795
+ self.default = other.default
796
+ end
797
+
798
+ self
976
799
  end
977
800
 
978
801
  def select(&block)
979
- return enum_for :select unless block
802
+ return enum_for(:select){self.size} unless block
980
803
 
981
804
  %x{
982
- var keys = self.keys,
983
- _map = self.map,
984
- smap = self.smap,
985
- result = Opal.hash(),
986
- _map2 = result.map,
987
- smap2 = result.smap,
988
- keys2 = result.keys,
989
- map, map2, key, khash, value, object;
990
-
991
- for (var i = 0, length = keys.length; i < length; i++) {
805
+ var hash = Opal.hash();
806
+
807
+ for (var i = 0, keys = self.keys, length = keys.length, key, value, obj; i < length; i++) {
992
808
  key = keys[i];
993
809
 
994
810
  if (key.$$is_string) {
995
- khash = key;
996
- map = smap;
997
- map2 = smap2;
811
+ value = self.smap[key];
998
812
  } else {
999
- khash = key.$hash();
1000
- map = _map;
1001
- map2 = _map2;
813
+ value = key.value;
814
+ key = key.key;
1002
815
  }
1003
816
 
1004
- value = map[khash];
1005
- object = block(key, value);
817
+ obj = block(key, value);
1006
818
 
1007
- if (object === $breaker) {
819
+ if (obj === $breaker) {
1008
820
  return $breaker.$v;
1009
821
  }
1010
822
 
1011
- if (object !== false && object !== nil) {
1012
- keys2.push(key);
1013
- map2[khash] = value;
823
+ if (obj !== false && obj !== nil) {
824
+ Opal.hash_put(hash, key, value);
1014
825
  }
1015
826
  }
1016
827
 
1017
- return result;
828
+ return hash;
1018
829
  }
1019
830
  end
1020
831
 
1021
832
  def select!(&block)
1022
- return enum_for :select! unless block
833
+ return enum_for(:select!){self.size} unless block
1023
834
 
1024
835
  %x{
1025
- var _map = self.map,
1026
- smap = self.smap,
1027
- keys = self.keys,
1028
- result = nil,
1029
- key, khash, value, object, map;
836
+ var result = nil;
1030
837
 
1031
- for (var i = 0, length = keys.length; i < length; i++) {
838
+ for (var i = 0, keys = self.keys, length = keys.length, key, value, obj; i < length; i++) {
1032
839
  key = keys[i];
1033
840
 
1034
841
  if (key.$$is_string) {
1035
- khash = key;
1036
- map = smap;
842
+ value = self.smap[key];
1037
843
  } else {
1038
- khash = key.$hash();
1039
- map = _map;
844
+ value = key.value;
845
+ key = key.key;
1040
846
  }
1041
847
 
1042
- value = map[khash];
1043
- object = block(key, value);
848
+ obj = block(key, value);
1044
849
 
1045
- if (object === $breaker) {
850
+ if (obj === $breaker) {
1046
851
  return $breaker.$v;
1047
852
  }
1048
853
 
1049
- if (object === false || object === nil) {
1050
- keys.splice(i, 1);
1051
- delete map[khash];
1052
-
1053
- length--;
1054
- i--;
1055
- result = self
854
+ if (obj === false || obj === nil) {
855
+ if (Opal.hash_delete(self, key) !== undefined) {
856
+ length--;
857
+ i--;
858
+ }
859
+ result = self;
1056
860
  }
1057
861
  }
1058
862
 
@@ -1063,28 +867,17 @@ class Hash
1063
867
  def shift
1064
868
  %x{
1065
869
  var keys = self.keys,
1066
- _map = self.map,
1067
- smap = self.smap,
1068
- map, key, khash, value;
870
+ key;
1069
871
 
1070
- if (keys.length) {
872
+ if (keys.length > 0) {
1071
873
  key = keys[0];
1072
- if (key.$$is_string) {
1073
- khash = key;
1074
- map = smap;
1075
- } else {
1076
- khash = key.$hash();
1077
- map = _map;
1078
- }
1079
- value = map[khash];
1080
874
 
1081
- delete map[khash];
1082
- keys.splice(0, 1);
875
+ key = key.$$is_string ? key : key.key;
1083
876
 
1084
- return [key, value];
877
+ return [key, Opal.hash_delete(self, key)];
1085
878
  }
1086
879
 
1087
- return nil;
880
+ return self.$default(nil);
1088
881
  }
1089
882
  end
1090
883
 
@@ -1094,24 +887,19 @@ class Hash
1094
887
 
1095
888
  def to_a
1096
889
  %x{
1097
- var keys = self.keys,
1098
- _map = self.map,
1099
- smap = self.smap,
1100
- result = [],
1101
- map, key, khash;
890
+ var result = [];
1102
891
 
1103
- for (var i = 0, length = keys.length; i < length; i++) {
892
+ for (var i = 0, keys = self.keys, length = keys.length, key, value; i < length; i++) {
1104
893
  key = keys[i];
1105
894
 
1106
895
  if (key.$$is_string) {
1107
- khash = key;
1108
- map = smap;
896
+ value = self.smap[key];
1109
897
  } else {
1110
- khash = key.$hash();
1111
- map = _map;
898
+ value = key.value;
899
+ key = key.key;
1112
900
  }
1113
901
 
1114
- result.push([key, map[khash]]);
902
+ result.push([key, value]);
1115
903
  }
1116
904
 
1117
905
  return result;
@@ -1121,17 +909,13 @@ class Hash
1121
909
  def to_h
1122
910
  %x{
1123
911
  if (self.$$class === Opal.Hash) {
1124
- return self
912
+ return self;
1125
913
  }
1126
914
 
1127
- var hash = new Opal.Hash.$$alloc,
1128
- cloned = #{clone};
915
+ var hash = new Opal.Hash.$$alloc();
1129
916
 
1130
- hash.map = cloned.map;
1131
- hash.smap = cloned.smap;
1132
- hash.keys = cloned.keys;
1133
- hash.none = cloned.none;
1134
- hash.proc = cloned.proc;
917
+ Opal.hash_init(hash);
918
+ Opal.hash_clone(self, hash);
1135
919
 
1136
920
  return hash;
1137
921
  }
@@ -1151,24 +935,16 @@ class Hash
1151
935
 
1152
936
  def values
1153
937
  %x{
1154
- var _map = self.map,
1155
- smap = self.smap,
1156
- keys = self.keys,
1157
- result = [],
1158
- map, khash, key;
938
+ var result = [];
1159
939
 
1160
- for (var i = 0, length = keys.length; i < length; i++) {
940
+ for (var i = 0, keys = self.keys, length = keys.length, key; i < length; i++) {
1161
941
  key = keys[i];
1162
942
 
1163
943
  if (key.$$is_string) {
1164
- khash = key;
1165
- map = smap;
944
+ result.push(self.smap[key]);
1166
945
  } else {
1167
- khash = key.$hash();
1168
- map = _map;
946
+ result.push(key.value);
1169
947
  }
1170
-
1171
- result.push(map[khash]);
1172
948
  }
1173
949
 
1174
950
  return result;