opal 0.8.1 → 0.9.0.beta1

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