opal 0.9.4 → 0.10.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitattributes +1 -0
- data/.gitignore +2 -3
- data/.gitmodules +5 -2
- data/.jshintrc +1 -8
- data/.rspec +1 -1
- data/.travis.yml +15 -23
- data/CHANGELOG.md +511 -326
- data/CODE_OF_CONDUCT.md +13 -15
- data/CONTRIBUTING.md +26 -216
- data/Gemfile +20 -12
- data/Guardfile +2 -2
- data/HACKING.md +230 -0
- data/README.md +6 -7
- data/bin/opal-mspec +1 -1
- data/config.ru +2 -2
- data/docs/faq.md +1 -1
- data/docs/source_maps.md +1 -1
- data/lib/opal.rb +1 -0
- data/lib/opal/builder.rb +1 -1
- data/lib/opal/cli.rb +30 -28
- data/lib/opal/cli_options.rb +3 -0
- data/lib/opal/cli_runners.rb +14 -1
- data/lib/opal/cli_runners/{apple_script.rb → applescript.rb} +3 -3
- data/lib/opal/cli_runners/nashorn.rb +2 -2
- data/lib/opal/cli_runners/nodejs.rb +2 -2
- data/lib/opal/cli_runners/phantom.js +24 -0
- data/lib/opal/cli_runners/phantomjs.rb +10 -10
- data/lib/opal/cli_runners/server.rb +3 -3
- data/lib/opal/compiler.rb +43 -4
- data/lib/opal/config.rb +3 -1
- data/lib/opal/errors.rb +13 -0
- data/lib/opal/fragment.rb +0 -13
- data/lib/opal/nodes.rb +10 -0
- data/lib/opal/nodes/args/initialize_kwargs.rb +28 -0
- data/lib/opal/nodes/args/kwarg.rb +29 -0
- data/lib/opal/nodes/args/kwoptarg.rb +29 -0
- data/lib/opal/nodes/args/kwrestarg.rb +39 -0
- data/lib/opal/nodes/args/mlhsarg.rb +79 -0
- data/lib/opal/nodes/args/normarg.rb +26 -0
- data/lib/opal/nodes/args/optarg.rb +27 -0
- data/lib/opal/nodes/args/post_args.rb +200 -0
- data/lib/opal/nodes/args/post_kwargs.rb +31 -0
- data/lib/opal/nodes/args/restarg.rb +33 -0
- data/lib/opal/nodes/base.rb +12 -0
- data/lib/opal/nodes/call.rb +92 -33
- data/lib/opal/nodes/def.rb +26 -169
- data/lib/opal/nodes/hash.rb +10 -4
- data/lib/opal/nodes/helpers.rb +6 -3
- data/lib/opal/nodes/inline_args.rb +61 -0
- data/lib/opal/nodes/iter.rb +73 -82
- data/lib/opal/nodes/logic.rb +12 -2
- data/lib/opal/nodes/masgn.rb +1 -2
- data/lib/opal/nodes/node_with_args.rb +141 -0
- data/lib/opal/nodes/rescue.rb +121 -43
- data/lib/opal/nodes/scope.rb +24 -5
- data/lib/opal/nodes/super.rb +122 -54
- data/lib/opal/nodes/top.rb +0 -12
- data/lib/opal/nodes/yield.rb +2 -13
- data/lib/opal/parser.rb +67 -39
- data/lib/opal/parser/grammar.rb +3319 -2961
- data/lib/opal/parser/grammar.y +234 -46
- data/lib/opal/parser/lexer.rb +105 -17
- data/lib/opal/parser/sexp.rb +4 -0
- data/lib/opal/paths.rb +4 -0
- data/lib/opal/regexp_anchors.rb +19 -1
- data/lib/opal/sprockets.rb +21 -18
- data/lib/opal/sprockets/environment.rb +0 -8
- data/lib/opal/sprockets/processor.rb +13 -16
- data/lib/opal/sprockets/server.rb +6 -12
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +1 -0
- data/opal/corelib/array.rb +209 -131
- data/opal/corelib/basic_object.rb +7 -3
- data/opal/corelib/class.rb +11 -17
- data/opal/corelib/constants.rb +2 -2
- data/opal/corelib/enumerable.rb +178 -355
- data/opal/corelib/enumerator.rb +3 -46
- data/opal/corelib/error.rb +2 -2
- data/opal/corelib/file.rb +13 -1
- data/opal/corelib/hash.rb +26 -56
- data/opal/corelib/helpers.rb +10 -0
- data/opal/corelib/kernel.rb +6 -3
- data/opal/corelib/module.rb +62 -31
- data/opal/corelib/number.rb +7 -16
- data/opal/corelib/proc.rb +24 -9
- data/opal/corelib/range.rb +4 -13
- data/opal/corelib/runtime.js +515 -378
- data/opal/corelib/string.rb +21 -49
- data/opal/corelib/struct.rb +50 -35
- data/opal/corelib/unsupported.rb +18 -30
- data/opal/opal.rb +0 -1
- data/opal/opal/mini.rb +1 -0
- data/spec/README.md +6 -4
- data/spec/filters/bugs/array.rb +0 -42
- data/spec/filters/bugs/basicobject.rb +0 -2
- data/spec/filters/bugs/bigdecimal.rb +160 -0
- data/spec/filters/bugs/class.rb +0 -5
- data/spec/filters/bugs/date.rb +1 -48
- data/spec/filters/bugs/enumerable.rb +4 -12
- data/spec/filters/bugs/enumerator.rb +0 -1
- data/spec/filters/bugs/exception.rb +4 -3
- data/spec/filters/bugs/float.rb +4 -2
- data/spec/filters/bugs/kernel.rb +25 -10
- data/spec/filters/bugs/language.rb +119 -68
- data/spec/filters/bugs/method.rb +135 -0
- data/spec/filters/bugs/module.rb +13 -28
- data/spec/filters/bugs/proc.rb +18 -8
- data/spec/filters/bugs/range.rb +0 -3
- data/spec/filters/bugs/rational.rb +4 -0
- data/spec/filters/bugs/regexp.rb +68 -36
- data/spec/filters/bugs/string.rb +1 -1
- data/spec/filters/bugs/struct.rb +0 -12
- data/spec/filters/bugs/time.rb +1 -0
- data/spec/filters/bugs/unboundmethod.rb +2 -1
- data/spec/filters/unsupported/freeze.rb +3 -1
- data/spec/filters/unsupported/language.rb +0 -7
- data/spec/filters/unsupported/privacy.rb +7 -6
- data/spec/filters/unsupported/string.rb +10 -0
- data/spec/filters/unsupported/struct.rb +3 -0
- data/spec/filters/unsupported/symbol.rb +9 -0
- data/spec/filters/unsupported/taint.rb +0 -3
- data/spec/filters/unsupported/thread.rb +1 -0
- data/spec/lib/cli_runners/phantomjs_spec.rb +39 -0
- data/spec/lib/cli_spec.rb +42 -1
- data/spec/lib/compiler/call_spec.rb +700 -0
- data/spec/lib/compiler_spec.rb +46 -28
- data/spec/lib/config_spec.rb +13 -0
- data/spec/lib/parser/call_spec.rb +18 -0
- data/spec/lib/parser/def_spec.rb +29 -0
- data/spec/lib/parser/iter_spec.rb +15 -15
- data/spec/lib/parser/lambda_spec.rb +153 -12
- data/spec/lib/parser/string_spec.rb +5 -0
- data/spec/lib/parser/undef_spec.rb +1 -1
- data/spec/lib/parser/variables_spec.rb +24 -0
- data/spec/lib/paths_spec.rb +12 -5
- data/spec/lib/spec_helper.rb +5 -0
- data/spec/lib/sprockets/processor_spec.rb +6 -5
- data/spec/lib/sprockets_spec.rb +8 -0
- data/spec/mspec-opal/formatters.rb +188 -0
- data/spec/mspec-opal/runner.rb +193 -0
- data/spec/opal/core/enumerator/with_index_spec.rb +6 -0
- data/spec/opal/core/kernel/define_singleton_method_spec.rb +1 -1
- data/spec/opal/core/kernel/instance_variables_spec.rb +14 -0
- data/spec/opal/core/kernel/loop_spec.rb +1 -1
- data/spec/opal/core/kernel/raise_spec.rb +1 -1
- data/spec/opal/core/language/heredoc_spec.rb +42 -0
- data/spec/opal/core/language/rescue_spec.rb +18 -0
- data/spec/opal/core/language_spec.rb +22 -0
- data/spec/opal/core/module/const_defined_spec.rb +1 -2
- data/spec/opal/core/module/name_spec.rb +6 -0
- data/spec/opal/core/runtime/bridged_classes_spec.rb +14 -2
- data/spec/opal/core/runtime/rescue_spec.rb +12 -2
- data/spec/opal/core/runtime/super_spec.rb +1 -0
- data/spec/opal/core/string_spec.rb +21 -0
- data/spec/opal/stdlib/js_spec.rb +1 -1
- data/spec/opal/stdlib/native/hash_spec.rb +7 -0
- data/spec/opal/stdlib/promise/always_spec.rb +24 -5
- data/spec/opal/stdlib/promise/rescue_spec.rb +15 -6
- data/spec/opal/stdlib/promise/then_spec.rb +13 -5
- data/spec/opal/stdlib/promise/trace_spec.rb +5 -6
- data/spec/opal/stdlib/strscan/scan_spec.rb +1 -1
- data/spec/ruby_specs +122 -0
- data/spec/spec_helper.rb +3 -15
- data/stdlib/base64.rb +51 -121
- data/stdlib/bigdecimal.rb +231 -0
- data/stdlib/bigdecimal/bignumber.js.rb +11 -0
- data/stdlib/bigdecimal/kernel.rb +5 -0
- data/stdlib/date.rb +252 -10
- data/stdlib/native.rb +38 -38
- data/stdlib/nodejs/dir.rb +8 -6
- data/stdlib/nodejs/file.rb +28 -3
- data/stdlib/nodejs/node_modules/.bin/js-yaml +1 -0
- data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esparse +1 -0
- data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esvalidate +1 -0
- data/stdlib/nodejs/require.rb +1 -1
- data/stdlib/nodejs/yaml.rb +3 -2
- data/stdlib/opal-parser.rb +7 -2
- data/stdlib/pathname.rb +23 -1
- data/stdlib/phantomjs.rb +10 -0
- data/stdlib/promise.rb +38 -23
- data/tasks/building.rake +3 -3
- data/tasks/testing.rake +27 -14
- data/tasks/testing/mspec_special_calls.rb +1 -1
- data/tasks/testing/sprockets-phantomjs.js +4 -0
- data/test/opal/test_keyword.rb +110 -110
- data/test/opal/unsupported_and_bugs.rb +30 -0
- data/vendored-minitest/minitest/assertions.rb +1 -1
- metadata +65 -15
- data/.spectator +0 -2
- data/.spectator-mspec +0 -3
- data/opal/corelib/array/inheritance.rb +0 -127
- data/spec/rubyspecs +0 -139
data/lib/opal/version.rb
CHANGED
data/opal.gemspec
CHANGED
data/opal/corelib/array.rb
CHANGED
@@ -7,8 +7,18 @@ class Array < `Array`
|
|
7
7
|
# Mark all javascript arrays as being valid ruby arrays
|
8
8
|
`def.$$is_array = true`
|
9
9
|
|
10
|
+
%x{
|
11
|
+
function toArraySubclass(obj, klass) {
|
12
|
+
if (klass.$$name === Opal.Array) {
|
13
|
+
return obj;
|
14
|
+
} else {
|
15
|
+
return klass.$allocate().$replace(#{`obj`.to_a});
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
10
20
|
def self.[](*objects)
|
11
|
-
objects
|
21
|
+
`toArraySubclass(objects, self)`
|
12
22
|
end
|
13
23
|
|
14
24
|
def initialize(size = nil, obj = nil, &block)
|
@@ -25,9 +35,11 @@ class Array < `Array`
|
|
25
35
|
|
26
36
|
if `arguments.length === 1`
|
27
37
|
if Array === size
|
28
|
-
|
38
|
+
replace(size.to_a)
|
39
|
+
return self
|
29
40
|
elsif size.respond_to? :to_ary
|
30
|
-
|
41
|
+
replace(size.to_ary)
|
42
|
+
return self
|
31
43
|
end
|
32
44
|
end
|
33
45
|
|
@@ -49,11 +61,6 @@ class Array < `Array`
|
|
49
61
|
else {
|
50
62
|
for (i = 0, value; i < size; i++) {
|
51
63
|
value = block(i);
|
52
|
-
|
53
|
-
if (value === $breaker) {
|
54
|
-
return $breaker.$v;
|
55
|
-
}
|
56
|
-
|
57
64
|
self[i] = value;
|
58
65
|
}
|
59
66
|
}
|
@@ -62,10 +69,6 @@ class Array < `Array`
|
|
62
69
|
}
|
63
70
|
end
|
64
71
|
|
65
|
-
def self.new(*args, &block)
|
66
|
-
[].initialize(*args, &block)
|
67
|
-
end
|
68
|
-
|
69
72
|
def self.try_convert(obj)
|
70
73
|
Opal.coerce_to? obj, Array, :to_ary
|
71
74
|
end
|
@@ -120,10 +123,6 @@ class Array < `Array`
|
|
120
123
|
def *(other)
|
121
124
|
return join(other.to_str) if other.respond_to? :to_str
|
122
125
|
|
123
|
-
unless other.respond_to? :to_int
|
124
|
-
raise TypeError, "no implicit conversion of #{other.class} into Integer"
|
125
|
-
end
|
126
|
-
|
127
126
|
other = Opal.coerce_to other, Integer, :to_int
|
128
127
|
|
129
128
|
if `other < 0`
|
@@ -131,13 +130,14 @@ class Array < `Array`
|
|
131
130
|
end
|
132
131
|
|
133
132
|
%x{
|
134
|
-
var result = []
|
133
|
+
var result = [],
|
134
|
+
converted = #{self.to_a};
|
135
135
|
|
136
136
|
for (var i = 0; i < other; i++) {
|
137
|
-
result = result.concat(
|
137
|
+
result = result.concat(converted);
|
138
138
|
}
|
139
139
|
|
140
|
-
return result;
|
140
|
+
return toArraySubclass(result, #{self.class});
|
141
141
|
}
|
142
142
|
end
|
143
143
|
|
@@ -159,7 +159,7 @@ class Array < `Array`
|
|
159
159
|
end
|
160
160
|
|
161
161
|
return [] if `self.length === 0`
|
162
|
-
return clone if `other.length === 0`
|
162
|
+
return clone.to_a if `other.length === 0`
|
163
163
|
|
164
164
|
%x{
|
165
165
|
var result = [], hash = #{{}}, i, length, item;
|
@@ -232,9 +232,9 @@ class Array < `Array`
|
|
232
232
|
}
|
233
233
|
|
234
234
|
if (array.constructor !== Array)
|
235
|
-
array = array
|
235
|
+
array = #{`array`.to_a};
|
236
236
|
if (other.constructor !== Array)
|
237
|
-
other = other
|
237
|
+
other = #{`other`.to_a};
|
238
238
|
|
239
239
|
if (array.length !== other.length) {
|
240
240
|
return false;
|
@@ -271,7 +271,7 @@ class Array < `Array`
|
|
271
271
|
def [](index, length = undefined)
|
272
272
|
%x{
|
273
273
|
var size = self.length,
|
274
|
-
exclude, from, to;
|
274
|
+
exclude, from, to, result;
|
275
275
|
|
276
276
|
if (index.$$is_range) {
|
277
277
|
exclude = index.exclude;
|
@@ -302,7 +302,7 @@ class Array < `Array`
|
|
302
302
|
to += 1;
|
303
303
|
}
|
304
304
|
|
305
|
-
|
305
|
+
result = self.slice(from, to)
|
306
306
|
}
|
307
307
|
else {
|
308
308
|
index = #{Opal.coerce_to(index, Integer, :to_int)};
|
@@ -329,9 +329,11 @@ class Array < `Array`
|
|
329
329
|
return nil;
|
330
330
|
}
|
331
331
|
|
332
|
-
|
332
|
+
result = self.slice(index, index + length);
|
333
333
|
}
|
334
334
|
}
|
335
|
+
|
336
|
+
return toArraySubclass(result, #{self.class})
|
335
337
|
}
|
336
338
|
end
|
337
339
|
|
@@ -483,10 +485,7 @@ class Array < `Array`
|
|
483
485
|
val = self[mid];
|
484
486
|
ret = block(val);
|
485
487
|
|
486
|
-
if (ret ===
|
487
|
-
return $breaker.$v;
|
488
|
-
}
|
489
|
-
else if (ret === true) {
|
488
|
+
if (ret === true) {
|
490
489
|
satisfied = val;
|
491
490
|
smaller = true;
|
492
491
|
}
|
@@ -527,10 +526,6 @@ class Array < `Array`
|
|
527
526
|
while (true) {
|
528
527
|
for (i = 0, length = self.length; i < length; i++) {
|
529
528
|
value = Opal.yield1(block, self[i]);
|
530
|
-
|
531
|
-
if (value === $breaker) {
|
532
|
-
return $breaker.$v;
|
533
|
-
}
|
534
529
|
}
|
535
530
|
}
|
536
531
|
}
|
@@ -543,10 +538,6 @@ class Array < `Array`
|
|
543
538
|
while (n > 0) {
|
544
539
|
for (i = 0, length = self.length; i < length; i++) {
|
545
540
|
value = Opal.yield1(block, self[i]);
|
546
|
-
|
547
|
-
if (value === $breaker) {
|
548
|
-
return $breaker.$v;
|
549
|
-
}
|
550
541
|
}
|
551
542
|
|
552
543
|
n--;
|
@@ -563,19 +554,6 @@ class Array < `Array`
|
|
563
554
|
self
|
564
555
|
end
|
565
556
|
|
566
|
-
def clone
|
567
|
-
copy = []
|
568
|
-
copy.copy_singleton_methods(self)
|
569
|
-
copy.initialize_clone(self)
|
570
|
-
copy
|
571
|
-
end
|
572
|
-
|
573
|
-
def dup
|
574
|
-
copy = []
|
575
|
-
copy.initialize_dup(self)
|
576
|
-
copy
|
577
|
-
end
|
578
|
-
|
579
557
|
def initialize_copy(other)
|
580
558
|
replace other
|
581
559
|
end
|
@@ -588,11 +566,6 @@ class Array < `Array`
|
|
588
566
|
|
589
567
|
for (var i = 0, length = self.length; i < length; i++) {
|
590
568
|
var value = Opal.yield1(block, self[i]);
|
591
|
-
|
592
|
-
if (value === $breaker) {
|
593
|
-
return $breaker.$v;
|
594
|
-
}
|
595
|
-
|
596
569
|
result.push(value);
|
597
570
|
}
|
598
571
|
|
@@ -606,11 +579,6 @@ class Array < `Array`
|
|
606
579
|
%x{
|
607
580
|
for (var i = 0, length = self.length; i < length; i++) {
|
608
581
|
var value = Opal.yield1(block, self[i]);
|
609
|
-
|
610
|
-
if (value === $breaker) {
|
611
|
-
return $breaker.$v;
|
612
|
-
}
|
613
|
-
|
614
582
|
self[i] = value;
|
615
583
|
}
|
616
584
|
}
|
@@ -680,6 +648,34 @@ class Array < `Array`
|
|
680
648
|
self
|
681
649
|
end
|
682
650
|
|
651
|
+
def repeated_combination(n)
|
652
|
+
num = Opal.coerce_to! n, Integer, :to_int
|
653
|
+
|
654
|
+
unless block_given?
|
655
|
+
return enum_for(:repeated_combination, num){ `binomial_coefficient(self.length + num - 1, num)` }
|
656
|
+
end
|
657
|
+
|
658
|
+
%x{
|
659
|
+
function iterate(max, from, buffer, self) {
|
660
|
+
if (buffer.length == max) {
|
661
|
+
var copy = buffer.slice();
|
662
|
+
#{yield `copy`}
|
663
|
+
return;
|
664
|
+
}
|
665
|
+
for (var i = from; i < self.length; i++) {
|
666
|
+
buffer.push(self[i]);
|
667
|
+
iterate(max, i, buffer, self);
|
668
|
+
buffer.pop();
|
669
|
+
}
|
670
|
+
}
|
671
|
+
|
672
|
+
if (num >= 0) {
|
673
|
+
iterate(num, 0, [], self);
|
674
|
+
}
|
675
|
+
}
|
676
|
+
self
|
677
|
+
end
|
678
|
+
|
683
679
|
def compact
|
684
680
|
%x{
|
685
681
|
var result = [];
|
@@ -775,9 +771,7 @@ class Array < `Array`
|
|
775
771
|
|
776
772
|
%x{
|
777
773
|
for (var i = 0, length = self.length, value; i < length; i++) {
|
778
|
-
|
779
|
-
return $breaker.$v;
|
780
|
-
}
|
774
|
+
value = block(self[i]);
|
781
775
|
|
782
776
|
if (value !== false && value !== nil) {
|
783
777
|
self.splice(i, 1);
|
@@ -807,10 +801,6 @@ class Array < `Array`
|
|
807
801
|
%x{
|
808
802
|
for (var i = 0, length = self.length; i < length; i++) {
|
809
803
|
var value = Opal.yield1(block, self[i]);
|
810
|
-
|
811
|
-
if (value == $breaker) {
|
812
|
-
return $breaker.$v;
|
813
|
-
}
|
814
804
|
}
|
815
805
|
}
|
816
806
|
|
@@ -823,10 +813,6 @@ class Array < `Array`
|
|
823
813
|
%x{
|
824
814
|
for (var i = 0, length = self.length; i < length; i++) {
|
825
815
|
var value = Opal.yield1(block, i);
|
826
|
-
|
827
|
-
if (value === $breaker) {
|
828
|
-
return $breaker.$v;
|
829
|
-
}
|
830
816
|
}
|
831
817
|
}
|
832
818
|
|
@@ -981,11 +967,6 @@ class Array < `Array`
|
|
981
967
|
%x{
|
982
968
|
for (length = #@length; left < right; left++) {
|
983
969
|
value = block(left);
|
984
|
-
|
985
|
-
if (value === $breaker) {
|
986
|
-
return $breaker.$v;
|
987
|
-
}
|
988
|
-
|
989
970
|
self[left] = value;
|
990
971
|
}
|
991
972
|
}
|
@@ -1050,7 +1031,7 @@ class Array < `Array`
|
|
1050
1031
|
|
1051
1032
|
switch (level) {
|
1052
1033
|
case undefined:
|
1053
|
-
result.
|
1034
|
+
result = result.concat(_flatten(ary));
|
1054
1035
|
break;
|
1055
1036
|
case 0:
|
1056
1037
|
result.push(ary);
|
@@ -1066,7 +1047,7 @@ class Array < `Array`
|
|
1066
1047
|
level = #{Opal.coerce_to(`level`, Integer, :to_int)};
|
1067
1048
|
}
|
1068
1049
|
|
1069
|
-
return _flatten(self, level);
|
1050
|
+
return toArraySubclass(_flatten(self, level), #{self.class});
|
1070
1051
|
}
|
1071
1052
|
end
|
1072
1053
|
|
@@ -1158,9 +1139,7 @@ class Array < `Array`
|
|
1158
1139
|
}
|
1159
1140
|
else if (block !== nil) {
|
1160
1141
|
for (i = 0, length = self.length; i < length; i++) {
|
1161
|
-
|
1162
|
-
return $breaker.$v;
|
1163
|
-
}
|
1142
|
+
value = block(self[i]);
|
1164
1143
|
|
1165
1144
|
if (value !== false && value !== nil) {
|
1166
1145
|
return i;
|
@@ -1285,9 +1264,7 @@ class Array < `Array`
|
|
1285
1264
|
|
1286
1265
|
%x{
|
1287
1266
|
for (var i = 0, length = self.length, value; i < length; i++) {
|
1288
|
-
|
1289
|
-
return $breaker.$v;
|
1290
|
-
}
|
1267
|
+
value = block(self[i]);
|
1291
1268
|
|
1292
1269
|
if (value === false || value === nil) {
|
1293
1270
|
self.splice(i, 1);
|
@@ -1329,8 +1306,23 @@ class Array < `Array`
|
|
1329
1306
|
|
1330
1307
|
alias map! collect!
|
1331
1308
|
|
1309
|
+
%x{
|
1310
|
+
// Returns the product of from, from-1, ..., from - how_many + 1.
|
1311
|
+
function descending_factorial(from, how_many) {
|
1312
|
+
var count = how_many >= 0 ? 1 : 0;
|
1313
|
+
while (how_many) {
|
1314
|
+
count *= from;
|
1315
|
+
from--;
|
1316
|
+
how_many--;
|
1317
|
+
}
|
1318
|
+
return count;
|
1319
|
+
}
|
1320
|
+
}
|
1321
|
+
|
1332
1322
|
def permutation(num = undefined, &block)
|
1333
|
-
|
1323
|
+
unless block_given?
|
1324
|
+
return enum_for(:permutation, num){ `descending_factorial(self.length, num === undefined ? self.length : num)` }
|
1325
|
+
end
|
1334
1326
|
|
1335
1327
|
%x{
|
1336
1328
|
var permute, offensive, output;
|
@@ -1395,6 +1387,30 @@ class Array < `Array`
|
|
1395
1387
|
self
|
1396
1388
|
end
|
1397
1389
|
|
1390
|
+
def repeated_permutation(n)
|
1391
|
+
num = Opal.coerce_to! n, Integer, :to_int
|
1392
|
+
return enum_for(:repeated_permutation, num){ num >= 0 ? self.size ** num : 0 } unless block_given?
|
1393
|
+
|
1394
|
+
%x{
|
1395
|
+
function iterate(max, buffer, self) {
|
1396
|
+
if (buffer.length == max) {
|
1397
|
+
var copy = buffer.slice();
|
1398
|
+
#{yield `copy`}
|
1399
|
+
return;
|
1400
|
+
}
|
1401
|
+
for (var i = 0; i < self.length; i++) {
|
1402
|
+
buffer.push(self[i]);
|
1403
|
+
iterate(max, buffer, self);
|
1404
|
+
buffer.pop();
|
1405
|
+
}
|
1406
|
+
}
|
1407
|
+
|
1408
|
+
iterate(num, [], self.slice());
|
1409
|
+
}
|
1410
|
+
|
1411
|
+
self
|
1412
|
+
end
|
1413
|
+
|
1398
1414
|
def pop(count = undefined)
|
1399
1415
|
if `count === undefined`
|
1400
1416
|
return if `self.length === 0`
|
@@ -1499,9 +1515,7 @@ class Array < `Array`
|
|
1499
1515
|
var result = [];
|
1500
1516
|
|
1501
1517
|
for (var i = 0, length = self.length, value; i < length; i++) {
|
1502
|
-
|
1503
|
-
return $breaker.$v;
|
1504
|
-
}
|
1518
|
+
value = block(self[i]);
|
1505
1519
|
|
1506
1520
|
if (value === false || value === nil) {
|
1507
1521
|
result.push(self[i]);
|
@@ -1571,9 +1585,9 @@ class Array < `Array`
|
|
1571
1585
|
if (i >= self.length) {
|
1572
1586
|
break;
|
1573
1587
|
}
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1588
|
+
|
1589
|
+
value = block(self[i]);
|
1590
|
+
|
1577
1591
|
if (value !== false && value !== nil) {
|
1578
1592
|
return i;
|
1579
1593
|
}
|
@@ -1753,9 +1767,7 @@ class Array < `Array`
|
|
1753
1767
|
for (var i = 0, length = self.length, item, value; i < length; i++) {
|
1754
1768
|
item = self[i];
|
1755
1769
|
|
1756
|
-
|
1757
|
-
return $breaker.$v;
|
1758
|
-
}
|
1770
|
+
value = Opal.yield1(block, item);
|
1759
1771
|
|
1760
1772
|
if (value !== false && value !== nil) {
|
1761
1773
|
result.push(item);
|
@@ -1796,7 +1808,7 @@ class Array < `Array`
|
|
1796
1808
|
alias size length
|
1797
1809
|
|
1798
1810
|
def shuffle(rng = undefined)
|
1799
|
-
dup.shuffle!(rng)
|
1811
|
+
dup.to_a.shuffle!(rng)
|
1800
1812
|
end
|
1801
1813
|
|
1802
1814
|
def shuffle!(rng = undefined)
|
@@ -1843,21 +1855,88 @@ class Array < `Array`
|
|
1843
1855
|
alias slice []
|
1844
1856
|
|
1845
1857
|
def slice!(index, length = undefined)
|
1846
|
-
|
1847
|
-
if (index < 0) {
|
1848
|
-
index += self.length;
|
1849
|
-
}
|
1858
|
+
result = nil
|
1850
1859
|
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1860
|
+
if `length === undefined`
|
1861
|
+
if Range === index
|
1862
|
+
range = index
|
1863
|
+
result = self[range]
|
1854
1864
|
|
1855
|
-
|
1856
|
-
|
1857
|
-
}
|
1865
|
+
range_start = Opal.coerce_to(range.begin, Integer, :to_int)
|
1866
|
+
range_end = Opal.coerce_to(range.end, Integer, :to_int)
|
1858
1867
|
|
1859
|
-
|
1860
|
-
|
1868
|
+
%x{
|
1869
|
+
if (range_start < 0) {
|
1870
|
+
range_start += self.length;
|
1871
|
+
}
|
1872
|
+
|
1873
|
+
if (range_end < 0) {
|
1874
|
+
range_end += self.length;
|
1875
|
+
} else if (range_end >= self.length) {
|
1876
|
+
range_end = self.length - 1;
|
1877
|
+
if (range.exclude) {
|
1878
|
+
range_end += 1;
|
1879
|
+
}
|
1880
|
+
}
|
1881
|
+
|
1882
|
+
var range_length = range_end - range_start;
|
1883
|
+
if (range.exclude) {
|
1884
|
+
range_end -= 1;
|
1885
|
+
} else {
|
1886
|
+
range_length += 1;
|
1887
|
+
}
|
1888
|
+
|
1889
|
+
if (range_start < self.length && range_start >= 0 && range_end < self.length && range_end >= 0 && range_length > 0) {
|
1890
|
+
self.splice(range_start, range_length);
|
1891
|
+
}
|
1892
|
+
}
|
1893
|
+
else
|
1894
|
+
start = Opal.coerce_to(index, Integer, :to_int)
|
1895
|
+
%x{
|
1896
|
+
if (start < 0) {
|
1897
|
+
start += self.length;
|
1898
|
+
}
|
1899
|
+
|
1900
|
+
if (start < 0 || start >= self.length) {
|
1901
|
+
return nil;
|
1902
|
+
}
|
1903
|
+
|
1904
|
+
result = self[start];
|
1905
|
+
|
1906
|
+
if (start === 0) {
|
1907
|
+
self.shift();
|
1908
|
+
} else {
|
1909
|
+
self.splice(start, 1);
|
1910
|
+
}
|
1911
|
+
}
|
1912
|
+
end
|
1913
|
+
else
|
1914
|
+
start = Opal.coerce_to(index, Integer, :to_int)
|
1915
|
+
length = Opal.coerce_to(length, Integer, :to_int)
|
1916
|
+
|
1917
|
+
%x{
|
1918
|
+
if (length < 0) {
|
1919
|
+
return nil;
|
1920
|
+
}
|
1921
|
+
|
1922
|
+
var end = start + length;
|
1923
|
+
|
1924
|
+
result = #{self[start, length]};
|
1925
|
+
|
1926
|
+
if (start < 0) {
|
1927
|
+
start += self.length;
|
1928
|
+
}
|
1929
|
+
|
1930
|
+
if (start + length > self.length) {
|
1931
|
+
length = self.length - start;
|
1932
|
+
}
|
1933
|
+
|
1934
|
+
if (start < self.length && start >= 0) {
|
1935
|
+
self.splice(start, length);
|
1936
|
+
}
|
1937
|
+
}
|
1938
|
+
end
|
1939
|
+
result
|
1861
1940
|
end
|
1862
1941
|
|
1863
1942
|
def sort(&block)
|
@@ -1870,28 +1949,15 @@ class Array < `Array`
|
|
1870
1949
|
};
|
1871
1950
|
}
|
1872
1951
|
|
1873
|
-
|
1874
|
-
|
1875
|
-
var ret = block(x, y);
|
1952
|
+
return self.slice().sort(function(x, y) {
|
1953
|
+
var ret = block(x, y);
|
1876
1954
|
|
1877
|
-
|
1878
|
-
|
1879
|
-
}
|
1880
|
-
else if (ret === nil) {
|
1881
|
-
#{raise ArgumentError, "comparison of #{`x`.inspect} with #{`y`.inspect} failed"};
|
1882
|
-
}
|
1883
|
-
|
1884
|
-
return #{`ret` > 0} ? 1 : (#{`ret` < 0} ? -1 : 0);
|
1885
|
-
});
|
1886
|
-
}
|
1887
|
-
catch (e) {
|
1888
|
-
if (e === $breaker) {
|
1889
|
-
return $breaker.$v;
|
1955
|
+
if (ret === nil) {
|
1956
|
+
#{raise ArgumentError, "comparison of #{`x`.inspect} with #{`y`.inspect} failed"};
|
1890
1957
|
}
|
1891
|
-
|
1892
|
-
|
1893
|
-
|
1894
|
-
}
|
1958
|
+
|
1959
|
+
return #{`ret` > 0} ? 1 : (#{`ret` < 0} ? -1 : 0);
|
1960
|
+
});
|
1895
1961
|
}
|
1896
1962
|
end
|
1897
1963
|
|
@@ -1915,6 +1981,12 @@ class Array < `Array`
|
|
1915
1981
|
}
|
1916
1982
|
end
|
1917
1983
|
|
1984
|
+
def sort_by!(&block)
|
1985
|
+
return enum_for(:sort_by!){self.size} unless block_given?
|
1986
|
+
|
1987
|
+
replace sort_by(&block)
|
1988
|
+
end
|
1989
|
+
|
1918
1990
|
def take(count)
|
1919
1991
|
%x{
|
1920
1992
|
if (count < 0) {
|
@@ -1932,9 +2004,7 @@ class Array < `Array`
|
|
1932
2004
|
for (var i = 0, length = self.length, item, value; i < length; i++) {
|
1933
2005
|
item = self[i];
|
1934
2006
|
|
1935
|
-
|
1936
|
-
return $breaker.$v;
|
1937
|
-
}
|
2007
|
+
value = block(item);
|
1938
2008
|
|
1939
2009
|
if (value === false || value === nil) {
|
1940
2010
|
return result;
|
@@ -2026,7 +2096,7 @@ class Array < `Array`
|
|
2026
2096
|
}
|
2027
2097
|
}
|
2028
2098
|
|
2029
|
-
return hash
|
2099
|
+
return toArraySubclass(#{`hash`.values}, #{self.class});
|
2030
2100
|
}
|
2031
2101
|
end
|
2032
2102
|
|
@@ -2149,4 +2219,12 @@ class Array < `Array`
|
|
2149
2219
|
return result;
|
2150
2220
|
}
|
2151
2221
|
end
|
2222
|
+
|
2223
|
+
def self.inherited(klass)
|
2224
|
+
%x{
|
2225
|
+
klass.$$proto.$to_a = function() {
|
2226
|
+
return this.slice(0, this.length);
|
2227
|
+
}
|
2228
|
+
}
|
2229
|
+
end
|
2152
2230
|
end
|