opal 0.3.18 → 0.3.19

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 (259) hide show
  1. data/.gitignore +1 -1
  2. data/Gemfile +1 -3
  3. data/README.md +472 -10
  4. data/Rakefile +10 -52
  5. data/core/array.rb +9 -14
  6. data/core/basic_object.rb +7 -10
  7. data/core/boolean.rb +5 -1
  8. data/core/class.rb +15 -38
  9. data/core/dir.rb +89 -0
  10. data/core/enumerable.rb +133 -57
  11. data/core/error.rb +15 -1
  12. data/core/file.rb +85 -0
  13. data/core/hash.rb +186 -32
  14. data/core/kernel.rb +30 -31
  15. data/core/load_order +4 -2
  16. data/core/module.rb +42 -62
  17. data/core/numeric.rb +7 -1
  18. data/core/object.rb +1 -1
  19. data/core/proc.rb +6 -2
  20. data/core/range.rb +16 -28
  21. data/core/regexp.rb +3 -3
  22. data/core/runtime.js +281 -350
  23. data/core/string.rb +100 -110
  24. data/docs/CNAME +1 -0
  25. data/docs/Rakefile +55 -0
  26. data/docs/css/styles.css +50 -0
  27. data/docs/css/syntax.css +63 -0
  28. data/docs/layout/post.html +3 -0
  29. data/docs/layout/pre.html +11 -0
  30. data/examples/dependencies/app.rb +3 -0
  31. data/lib/opal.rb +2 -1
  32. data/lib/opal/builder.rb +36 -10
  33. data/lib/opal/builder_task.rb +51 -24
  34. data/lib/opal/grammar.rb +2509 -2439
  35. data/lib/opal/grammar.y +38 -5
  36. data/lib/opal/lexer.rb +18 -2
  37. data/lib/opal/parser.rb +375 -349
  38. data/lib/opal/scope.rb +24 -2
  39. data/lib/opal/version.rb +1 -1
  40. data/spec/builder/build_order_spec.rb +20 -0
  41. data/spec/builder/lib_name_for_spec.rb +24 -0
  42. data/spec/grammar/call_spec.rb +9 -6
  43. data/spec/grammar/lambda_spec.rb +64 -0
  44. data/spec/grammar/sclass_spec.rb +5 -3
  45. data/{core/spec → test}/core/array/allocate_spec.rb +0 -0
  46. data/{core/spec → test}/core/array/append_spec.rb +0 -0
  47. data/{core/spec → test}/core/array/assoc_spec.rb +0 -0
  48. data/{core/spec → test}/core/array/at_spec.rb +0 -0
  49. data/{core/spec → test}/core/array/clear_spec.rb +0 -0
  50. data/{core/spec → test}/core/array/clone_spec.rb +0 -0
  51. data/{core/spec → test}/core/array/collect_spec.rb +0 -0
  52. data/{core/spec → test}/core/array/compact_spec.rb +0 -0
  53. data/{core/spec → test}/core/array/concat_spec.rb +0 -0
  54. data/{core/spec → test}/core/array/constructor_spec.rb +0 -0
  55. data/{core/spec → test}/core/array/count_spec.rb +0 -0
  56. data/{core/spec → test}/core/array/delete_at_spec.rb +0 -0
  57. data/{core/spec → test}/core/array/delete_if_spec.rb +0 -0
  58. data/{core/spec → test}/core/array/delete_spec.rb +0 -0
  59. data/{core/spec → test}/core/array/each_index_spec.rb +0 -0
  60. data/{core/spec → test}/core/array/each_spec.rb +0 -0
  61. data/{core/spec → test}/core/array/element_reference_spec.rb +0 -0
  62. data/{core/spec → test}/core/array/empty_spec.rb +0 -0
  63. data/{core/spec → test}/core/array/eql_spec.rb +0 -0
  64. data/{core/spec → test}/core/array/fetch_spec.rb +0 -0
  65. data/{core/spec → test}/core/array/first_spec.rb +0 -0
  66. data/{core/spec → test}/core/array/flatten_spec.rb +0 -0
  67. data/{core/spec → test}/core/array/include_spec.rb +0 -0
  68. data/{core/spec → test}/core/array/insert_spec.rb +0 -0
  69. data/{core/spec → test}/core/array/last_spec.rb +0 -0
  70. data/{core/spec → test}/core/array/length_spec.rb +0 -0
  71. data/{core/spec → test}/core/array/map_spec.rb +0 -0
  72. data/{core/spec → test}/core/array/plus_spec.rb +0 -0
  73. data/{core/spec → test}/core/array/pop_spec.rb +0 -0
  74. data/{core/spec → test}/core/array/push_spec.rb +0 -0
  75. data/{core/spec → test}/core/array/rassoc_spec.rb +0 -0
  76. data/{core/spec → test}/core/array/reject_spec.rb +0 -0
  77. data/{core/spec → test}/core/array/replace_spec.rb +0 -0
  78. data/{core/spec → test}/core/array/reverse_each_spec.rb +0 -0
  79. data/{core/spec → test}/core/array/reverse_spec.rb +0 -0
  80. data/{core/spec → test}/core/array/size_spec.rb +0 -0
  81. data/{core/spec → test}/core/array/to_ary_spec.rb +0 -0
  82. data/{core/spec → test}/core/array/uniq_spec.rb +0 -0
  83. data/{core/spec → test}/core/array/zip_spec.rb +0 -0
  84. data/test/core/class/fixtures/classes.rb +9 -0
  85. data/test/core/class/new_spec.rb +108 -0
  86. data/{core/spec → test}/core/enumerable/all_spec.rb +0 -0
  87. data/{core/spec → test}/core/enumerable/any_spec.rb +0 -0
  88. data/{core/spec → test}/core/enumerable/collect_spec.rb +0 -0
  89. data/{core/spec → test}/core/enumerable/count_spec.rb +0 -0
  90. data/test/core/enumerable/detect_spec.rb +48 -0
  91. data/test/core/enumerable/drop_spec.rb +17 -0
  92. data/test/core/enumerable/drop_while_spec.rb +24 -0
  93. data/test/core/enumerable/each_with_index_spec.rb +11 -0
  94. data/test/core/enumerable/each_with_object_spec.rb +17 -0
  95. data/test/core/enumerable/entries_spec.rb +6 -0
  96. data/test/core/enumerable/find_all_spec.rb +13 -0
  97. data/test/core/enumerable/find_index_spec.rb +45 -0
  98. data/test/core/enumerable/find_spec.rb +48 -0
  99. data/test/core/enumerable/first_spec.rb +40 -0
  100. data/{core/spec → test}/core/enumerable/fixtures/classes.rb +19 -0
  101. data/test/core/enumerable/grep_spec.rb +21 -0
  102. data/test/core/enumerable/take_spec.rb +40 -0
  103. data/test/core/enumerable/to_a_spec.rb +6 -0
  104. data/{core/spec → test}/core/false/and_spec.rb +0 -0
  105. data/{core/spec → test}/core/false/inspect_spec.rb +0 -0
  106. data/{core/spec → test}/core/false/or_spec.rb +0 -0
  107. data/{core/spec → test}/core/false/to_s_spec.rb +0 -0
  108. data/{core/spec → test}/core/false/xor_spec.rb +0 -0
  109. data/test/core/file/expand_path_spec.rb +20 -0
  110. data/{core/spec → test}/core/hash/allocate_spec.rb +0 -0
  111. data/{core/spec → test}/core/hash/assoc_spec.rb +0 -0
  112. data/{core/spec → test}/core/hash/clear_spec.rb +0 -0
  113. data/{core/spec → test}/core/hash/clone_spec.rb +0 -0
  114. data/test/core/hash/default_spec.rb +9 -0
  115. data/{core/spec → test}/core/hash/delete_if_spec.rb +0 -0
  116. data/test/core/hash/each_key_spec.rb +15 -0
  117. data/test/core/hash/each_pair_spec.rb +30 -0
  118. data/test/core/hash/each_spec.rb +30 -0
  119. data/test/core/hash/each_value_spec.rb +15 -0
  120. data/{core/spec → test}/core/hash/element_reference_spec.rb +14 -0
  121. data/{core/spec → test}/core/hash/element_set_spec.rb +1 -0
  122. data/test/core/hash/empty_spec.rb +10 -0
  123. data/test/core/hash/fetch_spec.rb +24 -0
  124. data/test/core/hash/flatten_spec.rb +46 -0
  125. data/test/core/hash/has_key_spec.rb +24 -0
  126. data/test/core/hash/has_value_spec.rb +12 -0
  127. data/test/core/hash/include_spec.rb +24 -0
  128. data/test/core/hash/index_spec.rb +13 -0
  129. data/test/core/hash/indexes_spec.rb +9 -0
  130. data/test/core/hash/indices_spec.rb +9 -0
  131. data/test/core/hash/invert_spec.rb +12 -0
  132. data/test/core/hash/keep_if_spec.rb +18 -0
  133. data/test/core/hash/key_spec.rb +24 -0
  134. data/test/core/hash/keys_spec.rb +10 -0
  135. data/test/core/hash/length_spec.rb +10 -0
  136. data/test/core/hash/member_spec.rb +24 -0
  137. data/{core/spec → test}/core/hash/merge_spec.rb +0 -0
  138. data/{core/spec → test}/core/hash/new_spec.rb +0 -0
  139. data/test/core/hash/rassoc_spec.rb +34 -0
  140. data/test/core/hash/replace_spec.rb +7 -0
  141. data/test/core/hash/select_spec.rb +52 -0
  142. data/test/core/hash/shift_spec.rb +19 -0
  143. data/test/core/hash/size_spec.rb +10 -0
  144. data/test/core/hash/update_spec.rb +17 -0
  145. data/test/core/hash/value_spec.rb +12 -0
  146. data/test/core/hash/values_at_spec.rb +9 -0
  147. data/test/core/hash/values_spec.rb +7 -0
  148. data/test/core/kernel/eql_spec.rb +15 -0
  149. data/test/core/kernel/equal_value_spec.rb +12 -0
  150. data/test/core/kernel/loop_spec.rb +23 -0
  151. data/test/core/kernel/nil_spec.rb +7 -0
  152. data/test/core/kernel/proc_spec.rb +9 -0
  153. data/test/core/kernel/rand_spec.rb +14 -0
  154. data/test/core/kernel/respond_to_spec.rb +24 -0
  155. data/test/core/kernel/send_spec.rb +56 -0
  156. data/test/core/kernel/tap_spec.rb +10 -0
  157. data/test/core/kernel/to_s_spec.rb +5 -0
  158. data/{core/spec → test}/core/matchdata/to_a_spec.rb +0 -0
  159. data/{core/spec → test}/core/nil/and_spec.rb +0 -0
  160. data/{core/spec → test}/core/nil/inspect_spec.rb +0 -0
  161. data/{core/spec → test}/core/nil/nil_spec.rb +0 -0
  162. data/{core/spec → test}/core/nil/or_spec.rb +0 -0
  163. data/{core/spec → test}/core/nil/to_a_spec.rb +0 -0
  164. data/{core/spec → test}/core/nil/to_f_spec.rb +0 -0
  165. data/{core/spec → test}/core/nil/to_i_spec.rb +0 -0
  166. data/{core/spec → test}/core/nil/to_s_spec.rb +0 -0
  167. data/{core/spec → test}/core/nil/xor_spec.rb +0 -0
  168. data/{core/spec → test}/core/numeric/equal_value_spec.rb +0 -0
  169. data/test/core/range/begin_spec.rb +9 -0
  170. data/test/core/range/case_compare_spec.rb +16 -0
  171. data/test/core/range/end_spec.rb +9 -0
  172. data/{core/spec → test}/core/regexp/match_spec.rb +0 -0
  173. data/test/core/string/capitalize_spec.rb +10 -0
  174. data/test/core/string/casecmp_spec.rb +16 -0
  175. data/test/core/string/chomp_spec.rb +43 -0
  176. data/test/core/string/chop_spec.rb +10 -0
  177. data/test/core/string/chr_spec.rb +13 -0
  178. data/test/core/string/comparison_spec.rb +13 -0
  179. data/test/core/string/downcase_spec.rb +6 -0
  180. data/test/core/string/element_reference_spec.rb +72 -0
  181. data/test/core/string/empty_spec.rb +8 -0
  182. data/test/core/string/end_with_spec.rb +12 -0
  183. data/test/core/string/fixtures/classes.rb +3 -0
  184. data/test/core/string/gsub_spec.rb +17 -0
  185. data/test/core/string/include_spec.rb +12 -0
  186. data/test/core/string/intern_spec.rb +9 -0
  187. data/test/core/string/length_spec.rb +9 -0
  188. data/test/core/string/lstrip_spec.rb +7 -0
  189. data/test/core/string/match_spec.rb +27 -0
  190. data/test/core/string/next_spec.rb +10 -0
  191. data/test/core/string/ord_spec.rb +9 -0
  192. data/test/core/string/partition_spec.rb +10 -0
  193. data/test/core/string/reverse_spec.rb +7 -0
  194. data/test/core/string/rstrip_spec.rb +7 -0
  195. data/test/core/string/size_spec.rb +9 -0
  196. data/test/core/string/slice_spec.rb +72 -0
  197. data/test/core/string/split_spec.rb +5 -0
  198. data/test/core/string/start_with_spec.rb +12 -0
  199. data/test/core/string/strip_spec.rb +6 -0
  200. data/test/core/string/sub_spec.rb +22 -0
  201. data/test/core/string/succ_spec.rb +10 -0
  202. data/test/core/string/sum_spec.rb +5 -0
  203. data/test/core/string/swapcase_spec.rb +18 -0
  204. data/test/core/string/to_a_spec.rb +9 -0
  205. data/test/core/string/to_f_spec.rb +14 -0
  206. data/test/core/string/to_i_spec.rb +25 -0
  207. data/test/core/string/to_s_spec.rb +13 -0
  208. data/test/core/string/to_str_spec.rb +13 -0
  209. data/test/core/string/to_sym_spec.rb +9 -0
  210. data/test/core/string/upcase_spec.rb +6 -0
  211. data/test/core/symbol/to_proc_spec.rb +12 -0
  212. data/{core/spec → test}/core/true/and_spec.rb +0 -0
  213. data/{core/spec → test}/core/true/inspect_spec.rb +0 -0
  214. data/{core/spec → test}/core/true/or_spec.rb +0 -0
  215. data/{core/spec → test}/core/true/to_s_spec.rb +0 -0
  216. data/{core/spec → test}/core/true/xor_spec.rb +0 -0
  217. data/test/index.html +11 -0
  218. data/{core/spec → test}/language/alias_spec.rb +4 -0
  219. data/{core/spec → test}/language/and_spec.rb +0 -0
  220. data/{core/spec → test}/language/array_spec.rb +0 -0
  221. data/{core/spec → test}/language/block_spec.rb +0 -0
  222. data/{core/spec → test}/language/break_spec.rb +0 -0
  223. data/{core/spec → test}/language/case_spec.rb +0 -0
  224. data/{core/spec → test}/language/defined_spec.rb +0 -0
  225. data/{core/spec → test}/language/ensure_spec.rb +0 -0
  226. data/test/language/fixtures/yield.rb +23 -0
  227. data/{core/spec → test}/language/hash_spec.rb +0 -0
  228. data/{core/spec → test}/language/if_spec.rb +0 -0
  229. data/test/language/literal_lambda_spec.rb +47 -0
  230. data/{core/spec → test}/language/loop_spec.rb +0 -0
  231. data/{core/spec → test}/language/metaclass_spec.rb +0 -0
  232. data/{core/spec → test}/language/next_spec.rb +0 -0
  233. data/{core/spec → test}/language/or_spec.rb +0 -0
  234. data/{core/spec → test}/language/predefined_spec.rb +0 -0
  235. data/{core/spec → test}/language/regexp_spec.rb +0 -0
  236. data/{core/spec → test}/language/send_spec.rb +0 -0
  237. data/{core/spec → test}/language/singleton_class_spec.rb +0 -0
  238. data/{core/spec → test}/language/super_spec.rb +0 -0
  239. data/{core/spec → test}/language/symbol_spec.rb +0 -0
  240. data/{core/spec → test}/language/undef_spec.rb +0 -0
  241. data/{core/spec → test}/language/unless_spec.rb +0 -0
  242. data/{core/spec → test}/language/until_spec.rb +0 -0
  243. data/{core/spec → test}/language/variables_spec.rb +0 -0
  244. data/{core/spec → test}/language/while_spec.rb +0 -0
  245. data/test/language/yield_spec.rb +100 -0
  246. data/test/opal/array/subclassing_spec.rb +32 -0
  247. data/test/opal/class/bridge_class_spec.rb +37 -0
  248. data/test/opal/exception/subclassing_spec.rb +17 -0
  249. data/test/opal/runtime/_methods_spec.rb +48 -0
  250. data/test/opal/runtime/class_hierarchy_spec.rb +22 -0
  251. data/test/opal/runtime/def_spec.rb +23 -0
  252. data/test/opal/string/subclassing_spec.rb +26 -0
  253. data/test/spec_helper.rb +3 -0
  254. metadata +437 -111
  255. data/core/spec/core/class/new_spec.rb +0 -16
  256. data/core/spec/core/hash/default_spec.rb +0 -4
  257. data/core/spec/core/symbol/to_proc_spec.rb +0 -6
  258. data/core/spec/index.html +0 -11
  259. data/spec/builder/build_source_spec.rb +0 -52
@@ -1,4 +1,4 @@
1
- class Exception
1
+ class Exception < `Error`
2
2
  def initialize(message = '')
3
3
  %x{
4
4
  if (Error.captureStackTrace) {
@@ -38,3 +38,17 @@ class Exception
38
38
 
39
39
  alias to_s message
40
40
  end
41
+
42
+ class StandardError < Exception; end
43
+ class RuntimeError < Exception; end
44
+ class LocalJumpError < StandardError; end
45
+ class TypeError < StandardError; end
46
+ class NameError < StandardError; end
47
+ class NoMethodError < NameError; end
48
+ class ArgumentError < StandardError; end
49
+ class ScriptError < Exception; end
50
+ class LoadError < ScriptError; end
51
+ class IndexError < StandardError; end
52
+ class KeyError < IndexError; end
53
+ class RangeError < StandardError; end
54
+ class NotImplementedError < Exception; end
@@ -0,0 +1,85 @@
1
+ class File
2
+ # Regexp to split path into dirname, basename and extname
3
+ PATH_RE = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/
4
+
5
+ def self.expand_path(path, base = undefined)
6
+ %x{
7
+ if (!base) {
8
+ base = '';
9
+ }
10
+
11
+ path = #{ join(base, path) };
12
+
13
+ var parts = path.split('/'), result = [], path;
14
+
15
+ for (var i = 0, ii = parts.length; i < ii; i++) {
16
+ part = parts[i];
17
+
18
+ if (part === '..') {
19
+ result.pop();
20
+ }
21
+ else if (part === '.' || part === '') {
22
+ // ignore?
23
+ }
24
+ else {
25
+ result.push(part);
26
+ }
27
+ }
28
+
29
+ return result.join('/');
30
+ }
31
+ end
32
+
33
+ def self.join(*paths)
34
+ %x{
35
+ var result = [];
36
+
37
+ for (var i = 0, length = paths.length; i < length; i++) {
38
+ var part = paths[i];
39
+
40
+ if (part != '') {
41
+ result.push(part);
42
+ }
43
+ }
44
+
45
+ return result.join('/');
46
+ }
47
+ end
48
+
49
+ def self.dirname(path)
50
+ %x{
51
+ var dirname = #{PATH_RE}.exec(path)[1];
52
+
53
+ if (!dirname) {
54
+ return '.';
55
+ }
56
+ else if (dirname === '/') {
57
+ return dirname;
58
+ }
59
+ else {
60
+ return dirname.substring(0, dirname.length - 1);
61
+ }
62
+ }
63
+ end
64
+
65
+ def self.extname(path)
66
+ %x{
67
+ var extname = #{PATH_RE}.exec(path)[3];
68
+
69
+ if (!extname || extname === '.') {
70
+ return '';
71
+ }
72
+ else {
73
+ return extname;
74
+ }
75
+ }
76
+ end
77
+
78
+ def self.basename(path, suffix)
79
+ ""
80
+ end
81
+
82
+ def self.exist?(path)
83
+ `!!factories[#{ expand_path path }]`
84
+ end
85
+ end
@@ -4,7 +4,7 @@ class Hash
4
4
  %x{
5
5
  var hash_class = this;
6
6
 
7
- Opal.hash = function() {
7
+ var __hash = Opal.hash = function() {
8
8
  var hash = new hash_class._alloc(),
9
9
  args = __slice.call(arguments),
10
10
  assocs = {};
@@ -13,7 +13,7 @@ class Hash
13
13
  hash.none = nil;
14
14
  hash.proc = nil;
15
15
 
16
- if (args.length == 1 && args[0]._flags & T_ARRAY) {
16
+ if (args.length == 1 && args[0]._isArray) {
17
17
  args = args[0];
18
18
 
19
19
  for (var i = 0, length = args.length, key; i < length; i++) {
@@ -38,21 +38,21 @@ class Hash
38
38
  }
39
39
 
40
40
  def self.[](*objs)
41
- `$opal.hash.apply(null, objs)`
41
+ `__hash.apply(null, objs)`
42
42
  end
43
43
 
44
44
  def self.allocate
45
- `Opal.hash()`
45
+ `__hash()`
46
46
  end
47
47
 
48
48
  def self.new(defaults = undefined, &block)
49
49
  %x{
50
- var hash = Opal.hash();
50
+ var hash = __hash();
51
51
 
52
- if (defaults != undefined) {
52
+ if (defaults != null) {
53
53
  hash.none = defaults;
54
54
  }
55
- else if (block != null) {
55
+ else if (block !== nil) {
56
56
  hash.proc = block;
57
57
  }
58
58
 
@@ -134,7 +134,7 @@ class Hash
134
134
 
135
135
  def clone
136
136
  %x{
137
- var result = Opal.hash(),
137
+ var result = __hash(),
138
138
  map = this.map,
139
139
  map2 = result.map;
140
140
 
@@ -199,6 +199,8 @@ class Hash
199
199
  }
200
200
  end
201
201
 
202
+ alias dup clone
203
+
202
204
  def each(&block)
203
205
  return enum_for :each unless block_given?
204
206
 
@@ -208,7 +210,7 @@ class Hash
208
210
  for (var assoc in map) {
209
211
  var bucket = map[assoc];
210
212
 
211
- if (block.call($context, null, bucket[0], bucket[1]) === $breaker) {
213
+ if (block.call(__context, bucket[0], bucket[1]) === __breaker) {
212
214
  return $breaker.$v;
213
215
  }
214
216
  }
@@ -226,8 +228,8 @@ class Hash
226
228
  for (var assoc in map) {
227
229
  var bucket = map[assoc];
228
230
 
229
- if (block.call($context, null, bucket[0]) === $breaker) {
230
- return $breaker.$v;
231
+ if (block.call(__context, bucket[0]) === __breaker) {
232
+ return __breaker.$v;
231
233
  }
232
234
  }
233
235
 
@@ -246,8 +248,8 @@ class Hash
246
248
  for (var assoc in map) {
247
249
  var bucket = map[assoc];
248
250
 
249
- if (block.call($context, null, bucket[1]) === $breaker) {
250
- return $breaker.$v;
251
+ if (block.call(__context, bucket[1]) === __breaker) {
252
+ return __breaker.$v;
251
253
  }
252
254
  }
253
255
 
@@ -271,17 +273,21 @@ class Hash
271
273
  %x{
272
274
  var bucket = this.map[key];
273
275
 
274
- if (block !== null) {
276
+ if (bucket) {
277
+ return bucket[1];
278
+ }
279
+
280
+ if (block !== nil) {
275
281
  var value;
276
282
 
277
- if ((value = block.call($context, null, key)) === $breaker) {
278
- return $breaker.$v;
283
+ if ((value = block.call(__context, key)) === __breaker) {
284
+ return __breaker.$v;
279
285
  }
280
286
 
281
287
  return value;
282
288
  }
283
289
 
284
- if (defaults !== undefined) {
290
+ if (defaults != null) {
285
291
  return defaults;
286
292
  }
287
293
 
@@ -301,8 +307,8 @@ class Hash
301
307
 
302
308
  result.push(key);
303
309
 
304
- if (value._flags & T_ARRAY) {
305
- if (level === undefined || level === 1) {
310
+ if (value._isArray) {
311
+ if (level == null || level === 1) {
306
312
  result.push(value);
307
313
  }
308
314
  else {
@@ -338,6 +344,43 @@ class Hash
338
344
  `this._id`
339
345
  end
340
346
 
347
+ alias include? has_key?
348
+
349
+ def index(object)
350
+ %x{
351
+ for (var assoc in this.map) {
352
+ var bucket = this.map[assoc];
353
+
354
+ if (#{object == `bucket[1]`}) {
355
+ return bucket[0];
356
+ }
357
+ }
358
+
359
+ return nil;
360
+ }
361
+ end
362
+
363
+ def indexes(*keys)
364
+ %x{
365
+ var result = [], map = this.map, bucket;
366
+
367
+ for (var i = 0, length = keys.length; i < length; i++) {
368
+ var key = keys[i];
369
+
370
+ if (bucket = map[key]) {
371
+ result.push(bucket[1]);
372
+ }
373
+ else {
374
+ result.push(this.none);
375
+ }
376
+ }
377
+
378
+ return result;
379
+ }
380
+ end
381
+
382
+ alias indices indexes
383
+
341
384
  def inspect
342
385
  %x{
343
386
  var inspect = [],
@@ -354,34 +397,44 @@ class Hash
354
397
 
355
398
  def invert
356
399
  %x{
357
- var result = $opal.hash(),
400
+ var result = __hash(),
358
401
  map = this.map,
359
402
  map2 = result.map;
360
403
 
361
404
  for (var assoc in map) {
362
405
  var bucket = map[assoc];
363
406
 
364
- map2[bucket[1]] = [bucket[0], bucket[1]];
407
+ map2[bucket[1]] = [bucket[1], bucket[0]];
365
408
  }
366
409
 
367
410
  return result;
368
411
  }
369
412
  end
370
413
 
371
- def key(object)
414
+ def keep_if(&block)
415
+ return enum_for :keep_if unless block_given?
416
+
372
417
  %x{
373
- for (var assoc in this.map) {
374
- var bucket = this.map[assoc];
418
+ var map = this.map, value;
375
419
 
376
- if (#{object == `bucket[1]`}) {
377
- return bucket[0];
420
+ for (var assoc in map) {
421
+ var bucket = map[assoc];
422
+
423
+ if ((value = block.call(__context, bucket[0], bucket[1])) === __breaker) {
424
+ return $breaker.$v;
425
+ }
426
+
427
+ if (value === false || value === nil) {
428
+ delete map[assoc];
378
429
  }
379
430
  }
380
431
 
381
- return null;
432
+ return this;
382
433
  }
383
434
  end
384
435
 
436
+ alias key index
437
+
385
438
  alias key? has_key?
386
439
 
387
440
  def keys
@@ -412,7 +465,7 @@ class Hash
412
465
 
413
466
  def merge(other, &block)
414
467
  %x{
415
- var result = Opal.hash(),
468
+ var result = __hash(),
416
469
  map = this.map,
417
470
  map2 = result.map;
418
471
 
@@ -424,7 +477,7 @@ class Hash
424
477
 
425
478
  map = other.map;
426
479
 
427
- if (block === null) {
480
+ if (block === nil) {
428
481
  for (var assoc in map) {
429
482
  var bucket = map[assoc];
430
483
 
@@ -452,7 +505,7 @@ class Hash
452
505
  var map = this.map,
453
506
  map2 = other.map;
454
507
 
455
- if (block == null || block === nil) {
508
+ if (block === nil) {
456
509
  for (var assoc in map2) {
457
510
  var bucket = map2[assoc];
458
511
 
@@ -487,7 +540,30 @@ class Hash
487
540
  }
488
541
  }
489
542
 
490
- return null;
543
+ return nil;
544
+ }
545
+ end
546
+
547
+ def reject(&block)
548
+ return enum_for :reject unless block_given?
549
+
550
+ %x{
551
+ var map = this.map, result = __hash(), map2 = result.map;
552
+
553
+ for (var assoc in map) {
554
+ var bucket = map[assoc],
555
+ value;
556
+
557
+ if ((value = block.call(__context, bucket[0], bucket[1])) === __breaker) {
558
+ return __breaker.$v;
559
+ }
560
+
561
+ if (value === false || value === nil) {
562
+ map2[bucket[0]] = [bucket[0], bucket[1]];
563
+ }
564
+ }
565
+
566
+ return result;
491
567
  }
492
568
  end
493
569
 
@@ -498,13 +574,74 @@ class Hash
498
574
  for (var assoc in other.map) {
499
575
  var bucket = other.map[assoc];
500
576
 
501
- map[assoc] = [bucket[0], bucket[1]];
577
+ map[bucket[0]] = [bucket[0], bucket[1]];
502
578
  }
503
579
 
504
580
  return this;
505
581
  }
506
582
  end
507
583
 
584
+ def select(&block)
585
+ return enum_for :select unless block_given?
586
+
587
+ %x{
588
+ var map = this.map, result = __hash(), map2 = result.map;
589
+
590
+ for (var assoc in map) {
591
+ var bucket = map[assoc],
592
+ value;
593
+
594
+ if ((value = block.call(__context, bucket[0], bucket[1])) === __breaker) {
595
+ return __breaker.$v;
596
+ }
597
+
598
+ if (value !== false && value !== nil) {
599
+ map2[bucket[0]] = [bucket[0], bucket[1]];
600
+ }
601
+ }
602
+
603
+ return result;
604
+ }
605
+ end
606
+
607
+ def select!(&block)
608
+ return enum_for :select! unless block_given?
609
+
610
+ %x{
611
+ var map = this.map, result = nil;
612
+
613
+ for (var assoc in map) {
614
+ var bucket = map[assoc],
615
+ value;
616
+
617
+ if ((value = block.call(__context, bucket[0], bucket[1])) === __breaker) {
618
+ return __breaker.$v;
619
+ }
620
+
621
+ if (value === false || value === nil) {
622
+ delete map[assoc];
623
+ result = this;
624
+ }
625
+ }
626
+
627
+ return result;
628
+ }
629
+ end
630
+
631
+ def shift
632
+ %x{
633
+ var map = this.map;
634
+
635
+ for (var assoc in map) {
636
+ var bucket = map[assoc];
637
+ delete map[assoc];
638
+ return [bucket[0], bucket[1]];
639
+ }
640
+
641
+ return nil;
642
+ }
643
+ end
644
+
508
645
  alias size length
509
646
 
510
647
  def to_a
@@ -530,6 +667,23 @@ class Hash
530
667
 
531
668
  alias update merge!
532
669
 
670
+ def value?(value)
671
+ %x{
672
+ var map = this.map;
673
+
674
+ for (var assoc in map) {
675
+ var v = map[assoc][1];
676
+ if (#{`v` == value}) {
677
+ return true;
678
+ }
679
+ }
680
+
681
+ return false;
682
+ }
683
+ end
684
+
685
+ alias values_at indexes
686
+
533
687
  def values
534
688
  %x{
535
689
  var map = this.map,