opal 0.3.10 → 0.3.11
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.
- data/README.md +47 -46
- data/lib/opal.rb +11 -3
- data/lib/opal/builder.rb +4 -46
- data/lib/opal/bundle.rb +11 -25
- data/lib/opal/command.rb +101 -22
- data/lib/opal/context.rb +16 -50
- data/lib/opal/lexer.rb +21 -2
- data/lib/opal/nodes.rb +134 -20
- data/lib/opal/parser.rb +7 -7
- data/lib/opal/parser.y +7 -7
- data/lib/opal/rake/bundle_task.rb +24 -23
- data/lib/opal/version.rb +3 -0
- data/opal-parser.js +8343 -0
- data/opal.js +5685 -0
- data/stdlib/dev.rb +6 -4
- data/templates/init/Rakefile +7 -0
- data/templates/init/index.html +17 -0
- data/templates/init/lib/__NAME__.rb +2 -0
- metadata +9 -32
- data/corelib/array.rb +0 -1424
- data/corelib/boolean.rb +0 -20
- data/corelib/class.rb +0 -58
- data/corelib/core.rb +0 -66
- data/corelib/dir.rb +0 -22
- data/corelib/enumerable.rb +0 -33
- data/corelib/error.rb +0 -19
- data/corelib/file.rb +0 -60
- data/corelib/hash.rb +0 -729
- data/corelib/kernel.rb +0 -251
- data/corelib/load_order +0 -21
- data/corelib/match_data.rb +0 -33
- data/corelib/module.rb +0 -101
- data/corelib/nil_class.rb +0 -54
- data/corelib/numeric.rb +0 -352
- data/corelib/object.rb +0 -37
- data/corelib/proc.rb +0 -55
- data/corelib/range.rb +0 -27
- data/corelib/regexp.rb +0 -69
- data/corelib/string.rb +0 -300
- data/corelib/top_self.rb +0 -8
- data/runtime/class.js +0 -386
- data/runtime/fs.js +0 -199
- data/runtime/init.js +0 -556
- data/runtime/loader.js +0 -330
- data/runtime/module.js +0 -103
- data/runtime/post.js +0 -10
- data/runtime/pre.js +0 -7
- data/runtime/runtime.js +0 -345
data/corelib/boolean.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
class Boolean
|
2
|
-
|
3
|
-
def to_s
|
4
|
-
# Yeah, this is another one for the wtf? collection. As the receiver
|
5
|
-
# is a true or false literal, it is coerced into a Boolean object,
|
6
|
-
# therefore it is always truthy. Therefore we comapre ourself with
|
7
|
-
# true to see if we are actually true or false. We could instead do
|
8
|
-
# `return self.valueOf() ? "true" : "false", but this way seems a
|
9
|
-
# little faster..
|
10
|
-
`return self == true ? "true" : "false";`
|
11
|
-
end
|
12
|
-
|
13
|
-
def ==(other)
|
14
|
-
`return self.valueOf() === other.valueOf();`
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
TRUE = true
|
19
|
-
FALSE = false
|
20
|
-
|
data/corelib/class.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
class Class < Module
|
2
|
-
|
3
|
-
def self.new(sup = Object)
|
4
|
-
`var res = rb_define_class_id('AnonClass', sup);
|
5
|
-
|
6
|
-
if (sup.m$inherited) {
|
7
|
-
sup.m$inherited(res);
|
8
|
-
}
|
9
|
-
|
10
|
-
return res;`
|
11
|
-
end
|
12
|
-
|
13
|
-
def allocate
|
14
|
-
`return new self.$a();`
|
15
|
-
end
|
16
|
-
|
17
|
-
def new(*args)
|
18
|
-
obj = allocate
|
19
|
-
|
20
|
-
`if ($B.f == arguments.callee) {
|
21
|
-
$B.f = obj.$m.initialize;
|
22
|
-
}`
|
23
|
-
|
24
|
-
obj.initialize *args
|
25
|
-
obj
|
26
|
-
end
|
27
|
-
|
28
|
-
def inherited(cls)
|
29
|
-
nil
|
30
|
-
end
|
31
|
-
|
32
|
-
def superclass
|
33
|
-
`var sup = self.$s;
|
34
|
-
|
35
|
-
if (!sup) {
|
36
|
-
if (self == rb_cObject) return nil;
|
37
|
-
throw new Error('RuntimeError: uninitialized class');
|
38
|
-
}
|
39
|
-
|
40
|
-
return sup;`
|
41
|
-
end
|
42
|
-
|
43
|
-
def native_prototype(proto)
|
44
|
-
`rb_native_prototype(self, proto);`
|
45
|
-
self
|
46
|
-
end
|
47
|
-
|
48
|
-
# Make the given object an instance of this class. This takes
|
49
|
-
# an **existing** object and adds the correct class, method
|
50
|
-
# table and id to the receiver.
|
51
|
-
#
|
52
|
-
# @param [NativeJSObject] obj
|
53
|
-
# @return [instance]
|
54
|
-
def from_native(obj)
|
55
|
-
`return rb_obj_from_native(obj, self);`
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
data/corelib/core.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
class Module
|
2
|
-
|
3
|
-
def include(*mods)
|
4
|
-
`var i = mods.length - 1, mod;
|
5
|
-
while (i >= 0) {
|
6
|
-
mod = mods[i];
|
7
|
-
#{`mod`.append_features self};
|
8
|
-
#{`mod`.included self};
|
9
|
-
i--;
|
10
|
-
}
|
11
|
-
return self;`
|
12
|
-
end
|
13
|
-
|
14
|
-
def append_features(mod)
|
15
|
-
`rb_include_module(mod, self);`
|
16
|
-
self
|
17
|
-
end
|
18
|
-
|
19
|
-
def included(mod)
|
20
|
-
nil
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
module Kernel
|
25
|
-
|
26
|
-
# Try to load the library or file named `path`. An error is thrown if the
|
27
|
-
# path cannot be resolved.
|
28
|
-
#
|
29
|
-
# @param [String] path The path to load
|
30
|
-
# @return [true, false]
|
31
|
-
def require(path)
|
32
|
-
`return rb_require(path);`
|
33
|
-
end
|
34
|
-
|
35
|
-
# Prints the message to `STDOUT`.
|
36
|
-
#
|
37
|
-
# @param [Array<Object>] args Objects to print using `to_s`
|
38
|
-
# @return [nil]
|
39
|
-
def puts(*a)
|
40
|
-
$stdout.puts *a
|
41
|
-
nil
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class << $stdout
|
46
|
-
# FIXME: Should this really be here? We only need to override this when we
|
47
|
-
# are in the browser context as we don't have native access to file
|
48
|
-
# descriptors etc
|
49
|
-
def puts(*a)
|
50
|
-
`for (var i = 0, ii = a.length; i < ii; i++) {
|
51
|
-
console.log(#{`a[i]`.to_s}.toString());
|
52
|
-
}`
|
53
|
-
nil
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
class Object
|
58
|
-
include Kernel
|
59
|
-
end
|
60
|
-
|
61
|
-
class String
|
62
|
-
def to_s
|
63
|
-
`return self.toString();`
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
data/corelib/dir.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
|
2
|
-
class Dir
|
3
|
-
|
4
|
-
# Returns a string that is the current working directory for this process.
|
5
|
-
#
|
6
|
-
# @return [String]
|
7
|
-
def self.getwd
|
8
|
-
`return Op.fs.cwd;`
|
9
|
-
end
|
10
|
-
|
11
|
-
# Returns a string that is the current working directory for this process.
|
12
|
-
#
|
13
|
-
# @return [String]
|
14
|
-
def self.pwd
|
15
|
-
`return Op.fs.cwd;`
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.[](*a)
|
19
|
-
`return Op.fs.glob.apply(Op.fs, a);`
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
data/corelib/enumerable.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
# The {Enumerable} module.
|
2
|
-
module Enumerable
|
3
|
-
|
4
|
-
# Returns an array containing the items in the receiver.
|
5
|
-
#
|
6
|
-
# @example
|
7
|
-
#
|
8
|
-
# (1..4).to_a # => [1, 2, 3, 4]
|
9
|
-
# [1, 2, 3].to_a # => [1, 2, 3]
|
10
|
-
#
|
11
|
-
# @return [Array]
|
12
|
-
def to_a
|
13
|
-
ary = []
|
14
|
-
each { |arg| `ary.push(arg);` }
|
15
|
-
ary
|
16
|
-
end
|
17
|
-
|
18
|
-
alias_method :entries, :to_a
|
19
|
-
|
20
|
-
def collect(&block)
|
21
|
-
raise "Enumerable#collect no block given" unless block_given?
|
22
|
-
`var result = [];`
|
23
|
-
|
24
|
-
each do |*args|
|
25
|
-
`result.push(#{block.call *args});`
|
26
|
-
end
|
27
|
-
|
28
|
-
`return result;`
|
29
|
-
end
|
30
|
-
|
31
|
-
alias_method :map, :collect
|
32
|
-
end
|
33
|
-
|
data/corelib/error.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
class Exception
|
2
|
-
|
3
|
-
def initialize(message = '')
|
4
|
-
@message = message
|
5
|
-
end
|
6
|
-
|
7
|
-
def message
|
8
|
-
@message
|
9
|
-
end
|
10
|
-
|
11
|
-
def inspect
|
12
|
-
`return "#<" + self.$k.__classid__ + ": '" + #{message} + "'>";`
|
13
|
-
end
|
14
|
-
|
15
|
-
def to_s
|
16
|
-
message
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
data/corelib/file.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
|
2
|
-
class File
|
3
|
-
|
4
|
-
# Converts the given `file_name` into its absolute path. The current working
|
5
|
-
# directory is used as the reference unless the `dir_string` is given, in
|
6
|
-
# which case that is used.
|
7
|
-
#
|
8
|
-
# @param [String] file_name
|
9
|
-
# @param [String] dir_string
|
10
|
-
# @return [String]
|
11
|
-
def self.expand_path(file_name, dir_string = nil)
|
12
|
-
if dir_string
|
13
|
-
`return Op.fs.expand_path(file_name, dir_string);`
|
14
|
-
else
|
15
|
-
`return Op.fs.expand_path(file_name);`
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# Returns a new string constructed by joining the given args with the default
|
20
|
-
# file separator.
|
21
|
-
#
|
22
|
-
# @param [String] str
|
23
|
-
# @return [String]
|
24
|
-
def self.join(*str)
|
25
|
-
`return Op.fs.join.apply(Op.fs, str);`
|
26
|
-
end
|
27
|
-
|
28
|
-
# Returns all the components of the given `file_name` except for the last
|
29
|
-
# one.
|
30
|
-
#
|
31
|
-
# @param [String] file_name
|
32
|
-
# @return [String]
|
33
|
-
def self.dirname(file_name)
|
34
|
-
`return Op.fs.dirname(file_name);`
|
35
|
-
end
|
36
|
-
|
37
|
-
# Returns the extension of the given filename.
|
38
|
-
#
|
39
|
-
# @param [String] file_name
|
40
|
-
# @return [String]
|
41
|
-
def self.extname(file_name)
|
42
|
-
`return Op.fs.extname(file_name);`
|
43
|
-
end
|
44
|
-
|
45
|
-
# Returns the last path component of the given `file_name`. If a suffix is
|
46
|
-
# given, and is present in the path, then it is removed. This is useful for
|
47
|
-
# removing file extensions, for example.
|
48
|
-
#
|
49
|
-
# @param [String] file_name
|
50
|
-
# @param [String] suffix
|
51
|
-
# @return [String]
|
52
|
-
def self.basename(file_name, suffix)
|
53
|
-
`return Op.fs.basename(file_name, suffix);`
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.exist?(path)
|
57
|
-
`return Op.fs.exist_p(path);`
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
data/corelib/hash.rb
DELETED
@@ -1,729 +0,0 @@
|
|
1
|
-
# A `Hash` is a collection of key-value pairs. It is similar to an array except
|
2
|
-
# that indexing is done via arbitrary keys of any object type, not an integer
|
3
|
-
# index. Hahses enumerate their values in the order that the corresponding keys
|
4
|
-
# were inserted.
|
5
|
-
#
|
6
|
-
# Hashes have a default value that is returned when accessing keys that do not
|
7
|
-
# exist in the hash. By default, that valus is `nil`.
|
8
|
-
#
|
9
|
-
# Implementation details
|
10
|
-
# ----------------------
|
11
|
-
#
|
12
|
-
# An Opal hash is actually toll-free bridged to a custom javascript
|
13
|
-
# prototype called RHash. This is all handled internally and is actually
|
14
|
-
# just an implementation detail, and is only done for the convenience of
|
15
|
-
# construction through literals and methods such as {Hash.new}.
|
16
|
-
#
|
17
|
-
# Although its syntax is similar to that of an object literal in
|
18
|
-
# javascript, it is very important to know that they are completely
|
19
|
-
# different, and a javascript/json object cannot be used in place of a
|
20
|
-
# ruby hash. All ruby objects require, at minimum, a `.$m` property
|
21
|
-
# which is their method table. When trying to send a message to a non
|
22
|
-
# ruby object, like a javascript object, errors will start occuring when
|
23
|
-
# this method table is not found.
|
24
|
-
#
|
25
|
-
# Hash and the JSON gem contain methods for converting native objects into
|
26
|
-
# `Hash` instances, so those should be used if you need to use objects from
|
27
|
-
# an external javascript library.
|
28
|
-
#
|
29
|
-
# Ruby compatibility
|
30
|
-
# ------------------
|
31
|
-
#
|
32
|
-
# `Hash` implements the majority of methods from the ruby standard
|
33
|
-
# library, and those that are not implemented are being added
|
34
|
-
# constantly.
|
35
|
-
#
|
36
|
-
# The `Enumerable` module is not yet implemented in opal, so most of the
|
37
|
-
# relevant methods used by `Hash` are implemented directly into this class.
|
38
|
-
# When `Enumerable` gets implemented, the relevant methods will be moved
|
39
|
-
# back into that module.
|
40
|
-
class Hash
|
41
|
-
|
42
|
-
# Creates a new hash populated with the given objects.
|
43
|
-
#
|
44
|
-
# @return [Hash]
|
45
|
-
def self.[](*args)
|
46
|
-
`return $rb.H.apply(null, args);`
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.allocate
|
50
|
-
`return $rb.H();`
|
51
|
-
end
|
52
|
-
|
53
|
-
# Returns a new array populated with the values from `self`.
|
54
|
-
#
|
55
|
-
# @example
|
56
|
-
#
|
57
|
-
# { :a => 1, :b => 2 }.values
|
58
|
-
# # => [1, 2]
|
59
|
-
#
|
60
|
-
# @return [Array]
|
61
|
-
def values
|
62
|
-
`var result = [], length = self.k.length;
|
63
|
-
|
64
|
-
for (var i = 0; i < length; i++) {
|
65
|
-
result.push(self.a[self.k[i].$h()]);
|
66
|
-
}
|
67
|
-
|
68
|
-
return result;`
|
69
|
-
end
|
70
|
-
|
71
|
-
# Returns the contents of this hash as a string.
|
72
|
-
#
|
73
|
-
# @example
|
74
|
-
#
|
75
|
-
# h = { 'a' => 100, 'b' => 200 }
|
76
|
-
# # => "{ \"a\" => 100, \"b\" => 200 }"
|
77
|
-
#
|
78
|
-
# @return [String]
|
79
|
-
def inspect
|
80
|
-
`var description = [], key, value;
|
81
|
-
|
82
|
-
for (var i = 0, ii = self.k.length; i < ii; i++) {
|
83
|
-
key = self.k[i];
|
84
|
-
value = self.a[key.$h()];
|
85
|
-
description.push(#{`key`.inspect} + '=>' + #{`value`.inspect});
|
86
|
-
}
|
87
|
-
|
88
|
-
return '{' + description.join(', ') + '}';`
|
89
|
-
end
|
90
|
-
|
91
|
-
# Returns a simple string representation of the hash's keys and values.
|
92
|
-
#
|
93
|
-
# @return [String]
|
94
|
-
def to_s
|
95
|
-
`var description = [], key, value;
|
96
|
-
|
97
|
-
for (var i = 0, ii = self.k.length; i < ii; i++) {
|
98
|
-
key = self.k[i];
|
99
|
-
value = self.a[key.$h()];
|
100
|
-
description.push(#{`key`.inspect} + #{`value`.inspect});
|
101
|
-
}
|
102
|
-
|
103
|
-
return description.join('');`
|
104
|
-
end
|
105
|
-
|
106
|
-
# Yields the block once for each key in `self`, passing the key-value pair
|
107
|
-
# as parameters.
|
108
|
-
#
|
109
|
-
# @example
|
110
|
-
#
|
111
|
-
# { 'a' => 100, 'b' => 200 }.each { |k, v| puts "#{k} is #{v}" }
|
112
|
-
# # => "a is 100"
|
113
|
-
# # => "b is 200"
|
114
|
-
#
|
115
|
-
# @return [Hash] returns the receiver
|
116
|
-
def each
|
117
|
-
`var keys = self.k, values = self.a, length = keys.length, key;
|
118
|
-
|
119
|
-
for (var i = 0; i < length; i++) {
|
120
|
-
key = keys[i];
|
121
|
-
#{yield `key`, `values[key.$h()]`};
|
122
|
-
}
|
123
|
-
|
124
|
-
return self;`
|
125
|
-
end
|
126
|
-
|
127
|
-
# Searches through the hash comparing `obj` with the key ysing ==. Returns the
|
128
|
-
# key-value pair (two element array) or nil if no match is found.
|
129
|
-
#
|
130
|
-
# @example
|
131
|
-
#
|
132
|
-
# h = { 'a' => [1, 2, 3], 'b' => [4, 5, 6] }
|
133
|
-
# h.assoc 'a'
|
134
|
-
# # => ['a', [1, 2, 3]]
|
135
|
-
# h.assoc 'c'
|
136
|
-
# # => nil
|
137
|
-
#
|
138
|
-
# @param [Object] obj key to search for
|
139
|
-
# @return [Array<Object, Object>, nil] result or nil
|
140
|
-
def assoc(obj)
|
141
|
-
`var key, keys = self.k, length = keys.length;
|
142
|
-
|
143
|
-
for (var i = 0; i < length; i++) {
|
144
|
-
key = keys[i];
|
145
|
-
if (#{`key` == obj}.$r) {
|
146
|
-
return [key, self.a[key.$h()]];
|
147
|
-
}
|
148
|
-
}
|
149
|
-
|
150
|
-
return nil;`
|
151
|
-
end
|
152
|
-
|
153
|
-
# Equality - Two hashes are equal if they each contain the same number of keys
|
154
|
-
# and if each key-value paid is equal, accordind to {BasicObject#==}, to the
|
155
|
-
# corresponding elements in the other hash.
|
156
|
-
#
|
157
|
-
# @example
|
158
|
-
#
|
159
|
-
# h1 = { 'a' => 1, 'c' => 2 }
|
160
|
-
# h2 = { 7 => 35, 'c' => 2, 'a' => 1 }
|
161
|
-
# h3 = { 'a' => 1, 'c' => 2, 7 => 35 }
|
162
|
-
# h4 = { 'a' => 1, 'd' => 2, 'f' => 35 }
|
163
|
-
#
|
164
|
-
# h1 == h2 # => false
|
165
|
-
# h2 == h3 # => true
|
166
|
-
# h3 == h4 # => false
|
167
|
-
#
|
168
|
-
# @param [Hash] other the hash to compare with
|
169
|
-
# @return [true, false]
|
170
|
-
def ==(other)
|
171
|
-
`if (self === other) return true;
|
172
|
-
if (!other.k || !other.a) return false;
|
173
|
-
if (self.k.length != other.k.length) return false;
|
174
|
-
|
175
|
-
for (var i = 0; i < self.k.length; i++) {
|
176
|
-
var key1 = self.k[i], assoc1 = key1.$h();
|
177
|
-
|
178
|
-
if (!hasOwnProperty.call(other.a, assoc1))
|
179
|
-
return false;
|
180
|
-
|
181
|
-
var assoc2 = other.a[assoc1];
|
182
|
-
|
183
|
-
if (!#{`self.a[assoc1]` == `assoc2`}.$r)
|
184
|
-
return false;
|
185
|
-
}
|
186
|
-
|
187
|
-
return true;`
|
188
|
-
end
|
189
|
-
|
190
|
-
# Element reference - retrieves the `value` object corresponding to the `key`
|
191
|
-
# object. If not found, returns the default value.
|
192
|
-
#
|
193
|
-
# @example
|
194
|
-
#
|
195
|
-
# h = { 'a' => 100, 'b' => 200 }
|
196
|
-
# h['a']
|
197
|
-
# # => 100
|
198
|
-
# h['c']
|
199
|
-
# # => nil
|
200
|
-
#
|
201
|
-
# @param [Object] key the key to look for
|
202
|
-
# @return [Object] result or default value
|
203
|
-
def [](key)
|
204
|
-
`var assoc = key.$h();
|
205
|
-
|
206
|
-
if (hasOwnProperty.call(self.a, assoc))
|
207
|
-
return self.a[assoc];
|
208
|
-
|
209
|
-
return self.d;`
|
210
|
-
end
|
211
|
-
|
212
|
-
# Element assignment - Associates the value given by 'value' with the key
|
213
|
-
# given by 'key'. `key` should not have its value changed while it is used as
|
214
|
-
# a key.
|
215
|
-
#
|
216
|
-
# @example
|
217
|
-
#
|
218
|
-
# h = { 'a' => 100, 'b' => 200 }
|
219
|
-
# h['a'] = 9
|
220
|
-
# h['c'] = 4
|
221
|
-
# h
|
222
|
-
# # => { 'a' => 9, 'b' => 200, 'c' => 4 }
|
223
|
-
#
|
224
|
-
# @param [Object] key the key for hash
|
225
|
-
# @param [Object] value the value for the key
|
226
|
-
# @return [Object] returns the set value
|
227
|
-
def []=(key, value)
|
228
|
-
`var assoc = key.$h();
|
229
|
-
|
230
|
-
if (!hasOwnProperty.call(self.a, assoc))
|
231
|
-
self.k.push(key);
|
232
|
-
|
233
|
-
return self.a[assoc] = value;`
|
234
|
-
end
|
235
|
-
|
236
|
-
# Remove all key-value pairs from `self`.
|
237
|
-
#
|
238
|
-
# @example
|
239
|
-
#
|
240
|
-
# h = { 'a' => 100, 'b' => 200 }
|
241
|
-
# h.clear
|
242
|
-
# # => {}
|
243
|
-
#
|
244
|
-
# @return [Hash]
|
245
|
-
def clear
|
246
|
-
`self.k = [];
|
247
|
-
self.a = {};
|
248
|
-
|
249
|
-
return self;`
|
250
|
-
end
|
251
|
-
|
252
|
-
# Returns the default value for the hash.
|
253
|
-
def default
|
254
|
-
`return self.d;`
|
255
|
-
end
|
256
|
-
|
257
|
-
# Sets the default value - the value returned when a key does not exist.
|
258
|
-
#
|
259
|
-
# @param [Object] obj the new default
|
260
|
-
# @return [Object] returns the new default
|
261
|
-
def default=(obj)
|
262
|
-
`return self.d = obj;`
|
263
|
-
end
|
264
|
-
|
265
|
-
# Deletes and returns a key-value pair from self whose key is equal to `key`.
|
266
|
-
# If the key is not found, returns the default value. If the optional code
|
267
|
-
# block is given and the key is not found, pass in the key and return the
|
268
|
-
# result of the block.
|
269
|
-
#
|
270
|
-
# @example
|
271
|
-
#
|
272
|
-
# h = { 'a' => 100, 'b' => 200 }
|
273
|
-
# h.delete 'a'
|
274
|
-
# # => 100
|
275
|
-
# h.delete 'z'
|
276
|
-
# # => nil
|
277
|
-
#
|
278
|
-
# @param [Object] key the key to delete
|
279
|
-
# #return [Object] returns value or default value
|
280
|
-
def delete(key)
|
281
|
-
`var assoc = key.$h();
|
282
|
-
|
283
|
-
if (hasOwnProperty.call(self.a, assoc)) {
|
284
|
-
var ret = self.a[assoc];
|
285
|
-
delete self.a[assoc];
|
286
|
-
self.k.splice(self.$keys.indexOf(key), 1);
|
287
|
-
return ret;
|
288
|
-
}
|
289
|
-
|
290
|
-
return self.d;`
|
291
|
-
end
|
292
|
-
|
293
|
-
# Deletes every key-value pair from `self` for which the block evaluates to
|
294
|
-
# `true`.
|
295
|
-
#
|
296
|
-
# @example
|
297
|
-
#
|
298
|
-
# h = { 'a' => 100, 'b' => 200, 'c' => 300 }
|
299
|
-
# h.delete_if { |k, v| key >= 'b' }
|
300
|
-
# # => { 'a' => 100 }
|
301
|
-
#
|
302
|
-
# @return [Hash] returns the receiver
|
303
|
-
def delete_if
|
304
|
-
`var key, value;
|
305
|
-
|
306
|
-
for (var i = 0; i < self.k.length; i++) {
|
307
|
-
key = self.k[i];
|
308
|
-
value = self.a[key.$h()];
|
309
|
-
|
310
|
-
if (#{yield `key`, `value`}.$r) {
|
311
|
-
delete self.a[key.$h()];
|
312
|
-
self.k.splice(i, 1);
|
313
|
-
i--;
|
314
|
-
}
|
315
|
-
}
|
316
|
-
|
317
|
-
return self;`
|
318
|
-
end
|
319
|
-
|
320
|
-
# Yields the block once for each key in `self`, passing the key as a param.
|
321
|
-
#
|
322
|
-
# @example
|
323
|
-
#
|
324
|
-
# h = { 'a' => 100, 'b' => 200, 'c' => 300 }
|
325
|
-
# h.each_key { |key| puts key }
|
326
|
-
# # => 'a'
|
327
|
-
# # => 'b'
|
328
|
-
# # => 'c'
|
329
|
-
#
|
330
|
-
# @return [Hash] returns receiver
|
331
|
-
def each_key
|
332
|
-
`for (var i = 0, ii = self.k.length; i < ii; i++) {
|
333
|
-
#{yield `self.k[i]`};
|
334
|
-
}
|
335
|
-
|
336
|
-
return self;`
|
337
|
-
end
|
338
|
-
|
339
|
-
# Yields the block once for each key in self, passing the associated value
|
340
|
-
# as a param.
|
341
|
-
#
|
342
|
-
# @example
|
343
|
-
#
|
344
|
-
# h = { 'a' => 100, 'b' => 200 }
|
345
|
-
# h.each_value { |a| puts a }
|
346
|
-
# # => 100
|
347
|
-
# # => 200
|
348
|
-
#
|
349
|
-
# @return [Hash] returns the receiver
|
350
|
-
def each_value
|
351
|
-
`var val;
|
352
|
-
|
353
|
-
for (var i = 0, ii = self.k.length; i < ii; i++) {
|
354
|
-
#{yield `self.a[self.k[i].$h()]`};
|
355
|
-
}
|
356
|
-
|
357
|
-
return self;`
|
358
|
-
end
|
359
|
-
|
360
|
-
# Returns `true` if `self` contains no key-value pairs, `false` otherwise.
|
361
|
-
#
|
362
|
-
# @example
|
363
|
-
#
|
364
|
-
# {}.empty?
|
365
|
-
# # => true
|
366
|
-
#
|
367
|
-
# @return [true, false]
|
368
|
-
def empty?
|
369
|
-
`return self.k.length == 0;`
|
370
|
-
end
|
371
|
-
|
372
|
-
# Returns a value from the hash for the given key. If the key can't be found,
|
373
|
-
# there are several options; with no other argument, it will raise a
|
374
|
-
# KeyError exception; if default is given, then that will be returned, if the
|
375
|
-
# optional code block if specified, then that will be run and its value
|
376
|
-
# returned.
|
377
|
-
#
|
378
|
-
# @example
|
379
|
-
#
|
380
|
-
# h = { 'a' => 100, 'b' => 200 }
|
381
|
-
# h.fetch 'a' # => 100
|
382
|
-
# h.fetch 'z', 'wow' # => 'wow'
|
383
|
-
# h.fetch 'z' # => KeyError
|
384
|
-
#
|
385
|
-
# @param [Object] key the key to lookup
|
386
|
-
# @param [Object] defaults the default value to return
|
387
|
-
# @return [Object] value from hash
|
388
|
-
def fetch(key, defaults = `undefined`)
|
389
|
-
`var value = self.a[key.$h()];
|
390
|
-
|
391
|
-
if (value != undefined)
|
392
|
-
return value;
|
393
|
-
else if (defaults == undefined)
|
394
|
-
rb_raise('KeyError: key not found');
|
395
|
-
else
|
396
|
-
return defaults;`
|
397
|
-
end
|
398
|
-
|
399
|
-
# Returns a new array that is a one dimensional flattening of this hash. That
|
400
|
-
# is, for every key or value that is an array, extraxt its elements into the
|
401
|
-
# new array. Unlike {Array#flatten}, this method does not flatten
|
402
|
-
# recursively by default. The optional `level` argument determines the level
|
403
|
-
# of recursion to flatten.
|
404
|
-
#
|
405
|
-
# @example
|
406
|
-
#
|
407
|
-
# a = { 1 => 'one', 2 => [2, 'two'], 3 => 'three' }
|
408
|
-
# a.flatten
|
409
|
-
# # => [1, 'one', 2, [2, 'two'], 3, 'three']
|
410
|
-
# a.flatten(2)
|
411
|
-
# # => [1, 'one', 2, 2, 'two', 3, 'three']
|
412
|
-
#
|
413
|
-
# @param [Numeric] level the level to flatten until
|
414
|
-
# @return [Array] flattened hash
|
415
|
-
def flatten(level = 1)
|
416
|
-
`var result = [], key, value;
|
417
|
-
|
418
|
-
for (var i = 0; i < self.k.length; i++) {
|
419
|
-
key = self.k[i];
|
420
|
-
value = self.a[key.$h()];
|
421
|
-
result.push(key);
|
422
|
-
|
423
|
-
if (value instanceof Array) {
|
424
|
-
if (level == 1) {
|
425
|
-
result.push(value);
|
426
|
-
} else {
|
427
|
-
var tmp = #{`value`.flatten `level - 1`};
|
428
|
-
result = result.concat(tmp);
|
429
|
-
}
|
430
|
-
} else {
|
431
|
-
result.push(value);
|
432
|
-
}
|
433
|
-
}
|
434
|
-
|
435
|
-
return result;`
|
436
|
-
end
|
437
|
-
|
438
|
-
# Returns `true` if the given `key` is present in `self`.
|
439
|
-
#
|
440
|
-
# @example
|
441
|
-
#
|
442
|
-
# h = { 'a' => 100, 'b' => 200 }
|
443
|
-
# h.has_key? 'a'
|
444
|
-
# # => true
|
445
|
-
# h.has_key? 'c'
|
446
|
-
# # => false
|
447
|
-
#
|
448
|
-
# @param [Object] key the key to check
|
449
|
-
# @return [true, false]
|
450
|
-
def has_key?(key)
|
451
|
-
`if (hasOwnProperty.call(self.a, key.$h()))
|
452
|
-
return true;
|
453
|
-
|
454
|
-
return false;`
|
455
|
-
end
|
456
|
-
|
457
|
-
# Returns `true` if the given `value` is present for some key in `self`.
|
458
|
-
#
|
459
|
-
# @example
|
460
|
-
#
|
461
|
-
# h = { 'a' => 100 }
|
462
|
-
# h.has_value? 100
|
463
|
-
# # => true
|
464
|
-
# h.has_value? 2020
|
465
|
-
# # => false
|
466
|
-
#
|
467
|
-
# @param [Object] value the value to check for
|
468
|
-
# @return [true, false]
|
469
|
-
def has_value?(value)
|
470
|
-
`var key, value;
|
471
|
-
|
472
|
-
for (var i = 0; i < self.k.length; i++) {
|
473
|
-
key = self.k[i];
|
474
|
-
val = self.a[key.$h()];
|
475
|
-
|
476
|
-
if (#{`value` == `val`}.$r)
|
477
|
-
return true;
|
478
|
-
}
|
479
|
-
|
480
|
-
return false;`
|
481
|
-
end
|
482
|
-
|
483
|
-
# Replaces the contents of `self` with the contents of `other`.
|
484
|
-
#
|
485
|
-
# @example
|
486
|
-
#
|
487
|
-
# h = { 'a' => 100, 'b' => 200 }
|
488
|
-
# h.replace({ 'c' => 200, 'd' => 300 })
|
489
|
-
# # => { 'c' => 200, 'd' => 300 }
|
490
|
-
#
|
491
|
-
# @param [Hash] other hash to replace with
|
492
|
-
# @return [Hash] returns receiver
|
493
|
-
def replace(other)
|
494
|
-
`self.k = []; self.a = {};
|
495
|
-
|
496
|
-
for (var i = 0; i < other.k.length; i++) {
|
497
|
-
var key = other.k[i];
|
498
|
-
var val = other.a[key.$h()];
|
499
|
-
self.k.push(key);
|
500
|
-
self.a[key.$h()] = val;
|
501
|
-
}
|
502
|
-
|
503
|
-
return self;`
|
504
|
-
end
|
505
|
-
|
506
|
-
# Returns a new hash created by using `self`'s vales as keys, and keys as
|
507
|
-
# values.
|
508
|
-
#
|
509
|
-
# @example
|
510
|
-
#
|
511
|
-
# h = { 'n' => 100, 'm' => 100, 'y' => 300 }
|
512
|
-
# h.invert
|
513
|
-
# # => { 100 => 'm', 300 => 'y' }
|
514
|
-
#
|
515
|
-
# @return [Hash] inverted hash
|
516
|
-
def invert
|
517
|
-
|
518
|
-
end
|
519
|
-
|
520
|
-
# Returns the key for the given value. If not found, returns `nil`.
|
521
|
-
#
|
522
|
-
# @example
|
523
|
-
#
|
524
|
-
# h = { 'a' => 100, 'b' => 200 }
|
525
|
-
# h.key 200
|
526
|
-
# # => 'b'
|
527
|
-
# h.key 300
|
528
|
-
# # => nil
|
529
|
-
#
|
530
|
-
# @param [Object] value the value to check for
|
531
|
-
# @return [Object] key or nil
|
532
|
-
def key(value)
|
533
|
-
`var key, val;
|
534
|
-
|
535
|
-
for (var i = 0; i < self.k.length; i++) {
|
536
|
-
key = self.k[i];
|
537
|
-
val = self.a[key.$h()];
|
538
|
-
|
539
|
-
if (#{`value` == `val`}.$r) {
|
540
|
-
return key;
|
541
|
-
}
|
542
|
-
}
|
543
|
-
|
544
|
-
return nil;`
|
545
|
-
end
|
546
|
-
|
547
|
-
# Returns a new array populated with the keys from this hash. See also
|
548
|
-
# {#values}.
|
549
|
-
#
|
550
|
-
# @example
|
551
|
-
#
|
552
|
-
# h = { 'a' => 100, 'b' => 200 }
|
553
|
-
# h.keys
|
554
|
-
# # => ['a', 'b']
|
555
|
-
#
|
556
|
-
# @return [Array]
|
557
|
-
def keys
|
558
|
-
`return self.k.slice(0);`
|
559
|
-
end
|
560
|
-
|
561
|
-
# Returns the number of key-value pairs in the hash.
|
562
|
-
#
|
563
|
-
# @example
|
564
|
-
#
|
565
|
-
# h = { 'a' => 100, 'b' => 200 }
|
566
|
-
# h.length
|
567
|
-
# # => 2
|
568
|
-
#
|
569
|
-
# @return [Numeric]
|
570
|
-
def length
|
571
|
-
`return self.k.length;`
|
572
|
-
end
|
573
|
-
|
574
|
-
# Returns a new hash containing the contents of `other` and `self`. If no
|
575
|
-
# block is specified, the value for the entries with duplicate keys will be
|
576
|
-
# that of `other`. Otherwise the value for each duplicate key is determined
|
577
|
-
# by calling the block with the key and its value in self, and its value in
|
578
|
-
# other.
|
579
|
-
#
|
580
|
-
# @example
|
581
|
-
#
|
582
|
-
# h1 = { 'a' => 100, 'b' => 200 }
|
583
|
-
# h2 = { 'b' => 300, 'c' => 400 }
|
584
|
-
# h1.merge h2
|
585
|
-
# # => {'a' => 100, 'b' => 300, 'c' => 400 }
|
586
|
-
# h1
|
587
|
-
# # => {'a' => 100, 'b' => 200}
|
588
|
-
#
|
589
|
-
# @param [Hash] other hash to merge with
|
590
|
-
# #return [Hash] returns new hash
|
591
|
-
def merge(other)
|
592
|
-
`var result = $opal.H() , key, val;
|
593
|
-
|
594
|
-
for (var i = 0; i < self.k.length; i++) {
|
595
|
-
key = self.k[i], val = self.a[key.$h()];
|
596
|
-
|
597
|
-
result.k.push(key);
|
598
|
-
result.a[key.$h()] = val;
|
599
|
-
}
|
600
|
-
|
601
|
-
for (var i = 0; i < other.k.length; i++) {
|
602
|
-
key = other.k[i], val = other.a[key.$h()];
|
603
|
-
|
604
|
-
if (!hasOwnProperty.call(result.a, key.$h())) {
|
605
|
-
result.k.push(key);
|
606
|
-
}
|
607
|
-
|
608
|
-
result.a[key.$h()] = val;
|
609
|
-
}
|
610
|
-
|
611
|
-
return result;`
|
612
|
-
end
|
613
|
-
|
614
|
-
# Merges the contents of `other` into `self`. If no block is given, entries
|
615
|
-
# with duplicate keys are overwritten with values from `other`.
|
616
|
-
#
|
617
|
-
# @example
|
618
|
-
#
|
619
|
-
# h1 = { 'a' => 100, 'b' => 200 }
|
620
|
-
# h2 = { 'b' => 300, 'c' => 400 }
|
621
|
-
# h1.merge! h2
|
622
|
-
# # => { 'a' => 100, 'b' => 300, 'c' => 400 }
|
623
|
-
# h1
|
624
|
-
# # => { 'a' => 100, 'b' => 300, 'c' => 400 }
|
625
|
-
#
|
626
|
-
# @param [Hash] other
|
627
|
-
# @return [Hash]
|
628
|
-
def merge!(other)
|
629
|
-
`var key, val;
|
630
|
-
|
631
|
-
for (var i = 0; i < other.k.length; i++) {
|
632
|
-
key = other.k[i];
|
633
|
-
val = other.a[key.$h()];
|
634
|
-
|
635
|
-
if (!hasOwnProperty.call(self.a, key.$h())) {
|
636
|
-
self.k.push(key);
|
637
|
-
}
|
638
|
-
|
639
|
-
self.a[key.$h()] = val;
|
640
|
-
}
|
641
|
-
|
642
|
-
return self;`
|
643
|
-
end
|
644
|
-
|
645
|
-
# Searches through the hash comparing `obj` with the value using ==. Returns
|
646
|
-
# the first key-value pair, as an array, that matches.
|
647
|
-
#
|
648
|
-
# @example
|
649
|
-
#
|
650
|
-
# a = { 1 => 'one', 2 => 'two', 3 => 'three' }
|
651
|
-
# a.rassoc 'two'
|
652
|
-
# # => [2, 'two']
|
653
|
-
# a.rassoc 'four'
|
654
|
-
# # => nil
|
655
|
-
#
|
656
|
-
# @param [Object] obj object to check
|
657
|
-
# @return [Array]
|
658
|
-
def rassoc(obj)
|
659
|
-
`var key, val;
|
660
|
-
|
661
|
-
for (var i = 0; i < self.k.length; i++) {
|
662
|
-
key = self.k[i];
|
663
|
-
val = self.a[key.$h()];
|
664
|
-
|
665
|
-
if (#{`val` == obj}.$r)
|
666
|
-
return [key, val];
|
667
|
-
}
|
668
|
-
|
669
|
-
return nil;`
|
670
|
-
end
|
671
|
-
|
672
|
-
# Removes a key-value pair from the hash and returns it as a two item array.
|
673
|
-
# Returns the default value if the hash is empty.
|
674
|
-
#
|
675
|
-
# @example
|
676
|
-
#
|
677
|
-
# h = { 'a' => 1, 'b' => 2 }
|
678
|
-
# h.shift
|
679
|
-
# # => ['a', 1]
|
680
|
-
# h
|
681
|
-
# # => { 'b' => 2 }
|
682
|
-
# {}.shift
|
683
|
-
# # => nil
|
684
|
-
#
|
685
|
-
# @return [Array, Object]
|
686
|
-
def shift
|
687
|
-
`var key, val;
|
688
|
-
|
689
|
-
if (self.k.length > 0) {
|
690
|
-
key = self.k[0];
|
691
|
-
val = self.a[key.$h()];
|
692
|
-
|
693
|
-
self.k.shift();
|
694
|
-
delete self.a[key.$h()];
|
695
|
-
return [key, val];
|
696
|
-
}
|
697
|
-
|
698
|
-
return self.d;`
|
699
|
-
end
|
700
|
-
|
701
|
-
# Convert self into a nested array of `[key, value]` arrays.
|
702
|
-
#
|
703
|
-
# @example
|
704
|
-
#
|
705
|
-
# h = { 'a' => 1, 'b' => 2, 'c' => 3 }
|
706
|
-
# h.to_a
|
707
|
-
# # => [['a', 1], ['b', 2], ['c', 3]]
|
708
|
-
#
|
709
|
-
# @return [Array]
|
710
|
-
def to_a
|
711
|
-
`var result = [], key, value;
|
712
|
-
|
713
|
-
for (var i = 0; i < self.k.length; i++) {
|
714
|
-
key = self.k[i];
|
715
|
-
value = self.a[key.$h()];
|
716
|
-
result.push([key, value]);
|
717
|
-
}
|
718
|
-
|
719
|
-
return result;`
|
720
|
-
end
|
721
|
-
|
722
|
-
# Returns self.
|
723
|
-
#
|
724
|
-
# @return [Hash]
|
725
|
-
def to_hash
|
726
|
-
self
|
727
|
-
end
|
728
|
-
end
|
729
|
-
|