opal 1.3.2 → 1.4.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc.js +1 -0
- data/.github/workflows/build.yml +0 -3
- data/.rubocop.yml +5 -1
- data/UNRELEASED.md +66 -2
- data/benchmark-ips/bm_truthy.rb +30 -0
- data/bin/opal-mspec +1 -3
- data/bin/opal-repl +1 -2
- data/bin/remove-filters +1 -4
- data/docs/compiled_ruby.md +10 -6
- data/exe/opal-repl +1 -3
- data/lib/opal/ast/builder.rb +1 -1
- data/lib/opal/cli.rb +2 -2
- data/lib/opal/cli_runners/nodejs.rb +9 -2
- data/lib/opal/cli_runners/source-map-support-browser.js +80 -216
- data/lib/opal/cli_runners/source-map-support-node.js +80 -216
- data/lib/opal/cli_runners/source-map-support.js +5 -1
- data/lib/opal/cli_runners/system_runner.rb +10 -4
- data/lib/opal/compiler.rb +3 -5
- data/lib/opal/fragment.rb +5 -1
- data/lib/opal/nodes/args/extract_block_arg.rb +1 -8
- data/lib/opal/nodes/args/extract_kwoptarg.rb +1 -3
- data/lib/opal/nodes/args/extract_optarg.rb +1 -3
- data/lib/opal/nodes/args/extract_post_arg.rb +2 -5
- data/lib/opal/nodes/args/extract_post_optarg.rb +2 -7
- data/lib/opal/nodes/args/initialize_iterarg.rb +1 -3
- data/lib/opal/nodes/args/prepare_post_args.rb +5 -1
- data/lib/opal/nodes/base.rb +3 -2
- data/lib/opal/nodes/call.rb +20 -9
- data/lib/opal/nodes/call_special.rb +50 -0
- data/lib/opal/nodes/class.rb +24 -15
- data/lib/opal/nodes/constants.rb +23 -5
- data/lib/opal/nodes/def.rb +20 -23
- data/lib/opal/nodes/defined.rb +5 -5
- data/lib/opal/nodes/definitions.rb +2 -2
- data/lib/opal/nodes/defs.rb +2 -5
- data/lib/opal/nodes/helpers.rb +48 -18
- data/lib/opal/nodes/if.rb +109 -8
- data/lib/opal/nodes/iter.rb +23 -16
- data/lib/opal/nodes/literal.rb +18 -4
- data/lib/opal/nodes/logic.rb +2 -1
- data/lib/opal/nodes/masgn.rb +4 -9
- data/lib/opal/nodes/module.rb +29 -19
- data/lib/opal/nodes/node_with_args.rb +1 -7
- data/lib/opal/nodes/scope.rb +54 -15
- data/lib/opal/nodes/singleton_class.rb +5 -3
- data/lib/opal/nodes/super.rb +3 -3
- data/lib/opal/nodes/top.rb +34 -31
- data/lib/opal/nodes/variables.rb +2 -2
- data/lib/opal/nodes/x_string.rb +3 -0
- data/lib/opal/nodes.rb +0 -1
- data/lib/opal/parser/patch.rb +75 -0
- data/lib/opal/parser/with_ruby_lexer.rb +1 -1
- data/lib/opal/regexp_anchors.rb +7 -7
- data/lib/opal/requires.rb +19 -0
- data/lib/opal/rewriters/pattern_matching.rb +1 -1
- data/lib/opal/rewriters/returnable_logic.rb +102 -4
- data/lib/opal/util.rb +2 -2
- data/lib/opal/version.rb +1 -1
- data/lib/opal.rb +1 -17
- data/opal/corelib/array/pack.rb +11 -11
- data/opal/corelib/array.rb +193 -152
- data/opal/corelib/basic_object.rb +14 -14
- data/opal/corelib/binding.rb +7 -7
- data/opal/corelib/boolean.rb +12 -15
- data/opal/corelib/class.rb +23 -1
- data/opal/corelib/comparable.rb +8 -8
- data/opal/corelib/complex/base.rb +2 -2
- data/opal/corelib/complex.rb +79 -88
- data/opal/corelib/constants.rb +9 -9
- data/opal/corelib/dir.rb +4 -3
- data/opal/corelib/enumerable.rb +140 -127
- data/opal/corelib/enumerator/arithmetic_sequence.rb +177 -0
- data/opal/corelib/enumerator/chain.rb +42 -0
- data/opal/corelib/enumerator/generator.rb +35 -0
- data/opal/corelib/enumerator/lazy.rb +243 -0
- data/opal/corelib/enumerator/yielder.rb +36 -0
- data/opal/corelib/enumerator.rb +45 -300
- data/opal/corelib/error/errno.rb +47 -0
- data/opal/corelib/error.rb +62 -60
- data/opal/corelib/file.rb +26 -12
- data/opal/corelib/hash.rb +98 -107
- data/opal/corelib/helpers.rb +62 -13
- data/opal/corelib/io.rb +47 -34
- data/opal/corelib/kernel/format.rb +29 -29
- data/opal/corelib/kernel.rb +86 -83
- data/opal/corelib/main.rb +14 -12
- data/opal/corelib/marshal/read_buffer.rb +15 -15
- data/opal/corelib/marshal/write_buffer.rb +45 -44
- data/opal/corelib/marshal.rb +3 -3
- data/opal/corelib/math.rb +50 -50
- data/opal/corelib/method.rb +12 -8
- data/opal/corelib/module.rb +96 -79
- data/opal/corelib/nil.rb +9 -11
- data/opal/corelib/number.rb +113 -118
- data/opal/corelib/numeric.rb +37 -33
- data/opal/corelib/object_space.rb +11 -10
- data/opal/corelib/pack_unpack/format_string_parser.rb +3 -3
- data/opal/corelib/pattern_matching/base.rb +7 -7
- data/opal/corelib/pattern_matching.rb +1 -1
- data/opal/corelib/proc.rb +15 -16
- data/opal/corelib/process/base.rb +2 -2
- data/opal/corelib/process/status.rb +21 -0
- data/opal/corelib/process.rb +5 -5
- data/opal/corelib/random/formatter.rb +11 -11
- data/opal/corelib/random/math_random.js.rb +1 -1
- data/opal/corelib/random/mersenne_twister.rb +3 -3
- data/opal/corelib/random/seedrandom.js.rb +3 -3
- data/opal/corelib/random.rb +17 -17
- data/opal/corelib/range.rb +51 -35
- data/opal/corelib/rational/base.rb +4 -4
- data/opal/corelib/rational.rb +61 -62
- data/opal/corelib/regexp.rb +47 -38
- data/opal/corelib/runtime.js +245 -139
- data/opal/corelib/string/encoding.rb +21 -21
- data/opal/corelib/string/unpack.rb +19 -14
- data/opal/corelib/string.rb +135 -128
- data/opal/corelib/struct.rb +59 -46
- data/opal/corelib/time.rb +47 -57
- data/opal/corelib/trace_point.rb +2 -2
- data/opal/corelib/unsupported.rb +31 -120
- data/opal/corelib/variables.rb +3 -3
- data/opal/opal/base.rb +9 -8
- data/opal/opal/full.rb +8 -8
- data/opal/opal/mini.rb +17 -17
- data/opal/opal.rb +17 -18
- data/opal.gemspec +1 -1
- data/spec/filters/bugs/array.rb +4 -24
- data/spec/filters/bugs/bigdecimal.rb +0 -23
- data/spec/filters/bugs/binding.rb +0 -1
- data/spec/filters/bugs/boolean.rb +3 -0
- data/spec/filters/bugs/class.rb +2 -0
- data/spec/filters/bugs/date.rb +0 -5
- data/spec/filters/bugs/encoding.rb +8 -50
- data/spec/filters/bugs/enumerable.rb +4 -1
- data/spec/filters/bugs/enumerator.rb +3 -36
- data/spec/filters/bugs/exception.rb +0 -2
- data/spec/filters/bugs/file.rb +0 -2
- data/spec/filters/bugs/float.rb +0 -3
- data/spec/filters/bugs/hash.rb +5 -3
- data/spec/filters/bugs/integer.rb +2 -3
- data/spec/filters/bugs/kernel.rb +2 -31
- data/spec/filters/bugs/language.rb +29 -49
- data/spec/filters/bugs/main.rb +0 -2
- data/spec/filters/bugs/marshal.rb +2 -3
- data/spec/filters/bugs/matrix.rb +0 -36
- data/spec/filters/bugs/module.rb +7 -61
- data/spec/filters/bugs/numeric.rb +0 -7
- data/spec/filters/bugs/objectspace.rb +1 -1
- data/spec/filters/bugs/pack_unpack.rb +0 -4
- data/spec/filters/bugs/proc.rb +0 -9
- data/spec/filters/bugs/random.rb +0 -5
- data/spec/filters/bugs/range.rb +1 -6
- data/spec/filters/bugs/regexp.rb +0 -3
- data/spec/filters/bugs/set.rb +8 -1
- data/spec/filters/bugs/string.rb +9 -34
- data/spec/filters/bugs/stringscanner.rb +8 -7
- data/spec/filters/bugs/struct.rb +2 -3
- data/spec/filters/bugs/symbol.rb +0 -1
- data/spec/filters/bugs/time.rb +0 -8
- data/spec/filters/bugs/unboundmethod.rb +0 -8
- data/spec/filters/bugs/warnings.rb +1 -7
- data/spec/filters/unsupported/freeze.rb +24 -0
- data/spec/filters/unsupported/integer.rb +1 -0
- data/spec/filters/unsupported/kernel.rb +12 -0
- data/spec/filters/unsupported/privacy.rb +3 -0
- data/spec/filters/unsupported/string.rb +2 -0
- data/spec/lib/builder_spec.rb +2 -2
- data/spec/lib/cli_spec.rb +1 -1
- data/spec/lib/compiler_spec.rb +37 -37
- data/spec/lib/simple_server_spec.rb +2 -2
- data/spec/lib/source_map/file_spec.rb +1 -1
- data/spec/opal/compiler/irb_spec.rb +2 -2
- data/spec/opal/core/kernel/puts_spec.rb +90 -0
- data/spec/opal/core/language/super_spec.rb +24 -0
- data/spec/ruby_specs +4 -2
- data/spec/support/rewriters_helper.rb +1 -1
- data/stdlib/bigdecimal.rb +7 -11
- data/stdlib/buffer/view.rb +2 -2
- data/stdlib/buffer.rb +2 -2
- data/stdlib/date.rb +5 -6
- data/stdlib/erb.rb +1 -0
- data/stdlib/js.rb +2 -1
- data/stdlib/native.rb +7 -8
- data/stdlib/nodejs/argf.rb +4 -4
- data/stdlib/nodejs/base.rb +29 -0
- data/stdlib/nodejs/dir.rb +1 -1
- data/stdlib/nodejs/env.rb +6 -9
- data/stdlib/nodejs/file.rb +23 -17
- data/stdlib/nodejs/fileutils.rb +3 -3
- data/stdlib/nodejs/io.rb +2 -20
- data/stdlib/nodejs/irb.rb +0 -0
- data/stdlib/nodejs/kernel.rb +2 -37
- data/stdlib/nodejs.rb +1 -3
- data/stdlib/opal/miniracer.rb +2 -0
- data/stdlib/opal/platform.rb +6 -13
- data/stdlib/opal/replutils.rb +16 -5
- data/stdlib/opal-parser.rb +2 -2
- data/stdlib/optparse/ac.rb +54 -0
- data/stdlib/optparse/date.rb +14 -0
- data/stdlib/optparse/kwargs.rb +22 -0
- data/stdlib/optparse/shellwords.rb +7 -0
- data/stdlib/optparse/time.rb +15 -0
- data/stdlib/optparse/uri.rb +7 -0
- data/stdlib/optparse/version.rb +69 -0
- data/stdlib/optparse.rb +2279 -0
- data/stdlib/pathname.rb +5 -6
- data/stdlib/pp.rb +18 -2
- data/stdlib/promise/v2.rb +18 -22
- data/stdlib/promise.rb +15 -21
- data/stdlib/set.rb +32 -32
- data/stdlib/shellwords.rb +240 -0
- data/stdlib/stringio.rb +3 -6
- data/stdlib/strscan.rb +5 -8
- data/stdlib/template.rb +2 -2
- data/stdlib/thread.rb +7 -9
- data/tasks/performance.rake +5 -2
- data/tasks/testing/mspec_special_calls.rb +0 -12
- data/tasks/testing.rake +55 -37
- data/test/nodejs/test_file.rb +11 -0
- metadata +55 -10
- data/lib/opal/nodes/case.rb +0 -114
data/stdlib/pathname.rb
CHANGED
@@ -165,12 +165,6 @@ class Pathname
|
|
165
165
|
path <=> other.path
|
166
166
|
end
|
167
167
|
|
168
|
-
alias eql? ==
|
169
|
-
alias === ==
|
170
|
-
|
171
|
-
alias to_str to_path
|
172
|
-
alias to_s to_path
|
173
|
-
|
174
168
|
SAME_PATHS = if File::FNM_SYSCASE.nonzero?
|
175
169
|
# Avoid #zero? here because #casecmp can return nil.
|
176
170
|
proc { |a, b| a.casecmp(b) == 0 }
|
@@ -217,6 +211,11 @@ class Pathname
|
|
217
211
|
def entries
|
218
212
|
Dir.entries(@path).map { |f| self.class.new(f) }
|
219
213
|
end
|
214
|
+
|
215
|
+
alias === ==
|
216
|
+
alias eql? ==
|
217
|
+
alias to_s to_path
|
218
|
+
alias to_str to_path
|
220
219
|
end
|
221
220
|
|
222
221
|
module Kernel
|
data/stdlib/pp.rb
CHANGED
@@ -151,7 +151,23 @@ class PP < PrettyPrint
|
|
151
151
|
#
|
152
152
|
# Object#pretty_print_cycle is used when +obj+ is already
|
153
153
|
# printed, a.k.a the object reference chain has a cycle.
|
154
|
-
def pp(obj)
|
154
|
+
def pp(obj = undefined)
|
155
|
+
# Opal: consider JS-native variables:
|
156
|
+
%x{
|
157
|
+
if (obj === null) {
|
158
|
+
#{text "null"}
|
159
|
+
#{return}
|
160
|
+
}
|
161
|
+
else if (obj === undefined) {
|
162
|
+
#{text "undefined"}
|
163
|
+
#{return}
|
164
|
+
}
|
165
|
+
else if (obj.$$class === undefined) {
|
166
|
+
#{text `Object.prototype.toString.apply(obj)`}
|
167
|
+
#{return}
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
155
171
|
# If obj is a Delegator then use the object being delegated to for cycle
|
156
172
|
# detection
|
157
173
|
obj = obj.__getobj__ if defined?(::Delegator) and obj.is_a?(::Delegator)
|
@@ -180,7 +196,7 @@ class PP < PrettyPrint
|
|
180
196
|
# object_id.
|
181
197
|
def object_address_group(obj, &block)
|
182
198
|
str = Kernel.instance_method(:to_s).bind_call(obj)
|
183
|
-
str.chomp
|
199
|
+
str = str.chomp('>')
|
184
200
|
group(1, str, '>', &block)
|
185
201
|
end
|
186
202
|
|
data/stdlib/promise/v2.rb
CHANGED
@@ -124,8 +124,6 @@ class PromiseV2 < `Promise`
|
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
127
|
-
alias all when
|
128
|
-
|
129
127
|
def all_resolved(*promises)
|
130
128
|
promises = Array(promises.length == 1 ? promises.first : promises)
|
131
129
|
`Promise.allResolved(#{promises})`.tap do |prom|
|
@@ -154,7 +152,6 @@ class PromiseV2 < `Promise`
|
|
154
152
|
prom.instance_variable_set(:@value, value)
|
155
153
|
end
|
156
154
|
end
|
157
|
-
alias value resolve
|
158
155
|
|
159
156
|
def reject(value = nil)
|
160
157
|
`Promise.reject(#{value})`.tap do |prom|
|
@@ -163,7 +160,10 @@ class PromiseV2 < `Promise`
|
|
163
160
|
prom.instance_variable_set(:@value, value)
|
164
161
|
end
|
165
162
|
end
|
163
|
+
|
164
|
+
alias all when
|
166
165
|
alias error reject
|
166
|
+
alias value resolve
|
167
167
|
end
|
168
168
|
|
169
169
|
attr_reader :prev, :next
|
@@ -209,7 +209,6 @@ class PromiseV2 < `Promise`
|
|
209
209
|
@resolve_proc.call(value)
|
210
210
|
self
|
211
211
|
end
|
212
|
-
alias resolve! resolve
|
213
212
|
|
214
213
|
def reject(value = nil)
|
215
214
|
nativity_check!
|
@@ -219,7 +218,6 @@ class PromiseV2 < `Promise`
|
|
219
218
|
@reject_proc.call(value)
|
220
219
|
self
|
221
220
|
end
|
222
|
-
alias reject! reject
|
223
221
|
|
224
222
|
def then(&block)
|
225
223
|
prom = nil
|
@@ -239,9 +237,6 @@ class PromiseV2 < `Promise`
|
|
239
237
|
self.then(&block)
|
240
238
|
end
|
241
239
|
|
242
|
-
alias do then
|
243
|
-
alias do! then!
|
244
|
-
|
245
240
|
def fail(&block)
|
246
241
|
prom = nil
|
247
242
|
blk = gen_tracing_proc(block) do |val|
|
@@ -260,11 +255,6 @@ class PromiseV2 < `Promise`
|
|
260
255
|
fail(&block)
|
261
256
|
end
|
262
257
|
|
263
|
-
alias rescue fail
|
264
|
-
alias catch fail
|
265
|
-
alias rescue! fail!
|
266
|
-
alias catch! fail!
|
267
|
-
|
268
258
|
def always(&block)
|
269
259
|
prom = nil
|
270
260
|
blk = gen_tracing_proc(block) do |val|
|
@@ -283,11 +273,6 @@ class PromiseV2 < `Promise`
|
|
283
273
|
always(&block)
|
284
274
|
end
|
285
275
|
|
286
|
-
alias finally always
|
287
|
-
alias ensure always
|
288
|
-
alias finally! always!
|
289
|
-
alias ensure! always!
|
290
|
-
|
291
276
|
def trace(depth = nil, &block)
|
292
277
|
prom = self.then do
|
293
278
|
values = []
|
@@ -362,8 +347,6 @@ class PromiseV2 < `Promise`
|
|
362
347
|
yield self if block_given?
|
363
348
|
end
|
364
349
|
|
365
|
-
alias to_v2 itself
|
366
|
-
|
367
350
|
def to_v1
|
368
351
|
v1 = PromiseV1.new
|
369
352
|
|
@@ -372,8 +355,6 @@ class PromiseV2 < `Promise`
|
|
372
355
|
v1
|
373
356
|
end
|
374
357
|
|
375
|
-
alias to_n itself
|
376
|
-
|
377
358
|
def inspect
|
378
359
|
result = "#<#{self.class}"
|
379
360
|
|
@@ -395,4 +376,19 @@ class PromiseV2 < `Promise`
|
|
395
376
|
|
396
377
|
result
|
397
378
|
end
|
379
|
+
|
380
|
+
alias catch fail
|
381
|
+
alias catch! fail!
|
382
|
+
alias do then
|
383
|
+
alias do! then!
|
384
|
+
alias ensure always
|
385
|
+
alias ensure! always!
|
386
|
+
alias finally always
|
387
|
+
alias finally! always!
|
388
|
+
alias reject! reject
|
389
|
+
alias rescue fail
|
390
|
+
alias rescue! fail!
|
391
|
+
alias resolve! resolve
|
392
|
+
alias to_n itself
|
393
|
+
alias to_v2 itself
|
398
394
|
end
|
data/stdlib/promise.rb
CHANGED
@@ -275,9 +275,6 @@ class Promise
|
|
275
275
|
self.then(&block)
|
276
276
|
end
|
277
277
|
|
278
|
-
alias do then
|
279
|
-
alias do! then!
|
280
|
-
|
281
278
|
def fail(&block)
|
282
279
|
self ^ Promise.new(failure: block)
|
283
280
|
end
|
@@ -287,11 +284,6 @@ class Promise
|
|
287
284
|
fail(&block)
|
288
285
|
end
|
289
286
|
|
290
|
-
alias rescue fail
|
291
|
-
alias catch fail
|
292
|
-
alias rescue! fail!
|
293
|
-
alias catch! fail!
|
294
|
-
|
295
287
|
def always(&block)
|
296
288
|
self ^ Promise.new(always: block)
|
297
289
|
end
|
@@ -301,11 +293,6 @@ class Promise
|
|
301
293
|
always(&block)
|
302
294
|
end
|
303
295
|
|
304
|
-
alias finally always
|
305
|
-
alias ensure always
|
306
|
-
alias finally! always!
|
307
|
-
alias ensure! always!
|
308
|
-
|
309
296
|
def trace(depth = nil, &block)
|
310
297
|
self ^ Trace.new(depth, block)
|
311
298
|
end
|
@@ -337,8 +324,6 @@ class Promise
|
|
337
324
|
result
|
338
325
|
end
|
339
326
|
|
340
|
-
alias to_v1 itself
|
341
|
-
|
342
327
|
def to_v2
|
343
328
|
v2 = PromiseV2.new
|
344
329
|
|
@@ -347,7 +332,18 @@ class Promise
|
|
347
332
|
v2
|
348
333
|
end
|
349
334
|
|
335
|
+
alias catch fail
|
336
|
+
alias catch! fail!
|
337
|
+
alias do then
|
338
|
+
alias do! then!
|
339
|
+
alias ensure always
|
340
|
+
alias ensure! always!
|
341
|
+
alias finally always
|
342
|
+
alias finally! always!
|
343
|
+
alias rescue fail
|
344
|
+
alias rescue! fail!
|
350
345
|
alias to_n to_v2
|
346
|
+
alias to_v1 itself
|
351
347
|
|
352
348
|
class Trace < self
|
353
349
|
def self.it(promise)
|
@@ -414,10 +410,6 @@ class Promise
|
|
414
410
|
end
|
415
411
|
end
|
416
412
|
|
417
|
-
alias map collect
|
418
|
-
|
419
|
-
alias reduce inject
|
420
|
-
|
421
413
|
def wait(promise)
|
422
414
|
unless Promise === promise
|
423
415
|
promise = Promise.value(promise)
|
@@ -436,8 +428,6 @@ class Promise
|
|
436
428
|
self
|
437
429
|
end
|
438
430
|
|
439
|
-
alias and wait
|
440
|
-
|
441
431
|
def >>(*)
|
442
432
|
super.tap do
|
443
433
|
try
|
@@ -454,6 +444,10 @@ class Promise
|
|
454
444
|
end
|
455
445
|
end
|
456
446
|
end
|
447
|
+
|
448
|
+
alias map collect
|
449
|
+
alias reduce inject
|
450
|
+
alias and wait
|
457
451
|
end
|
458
452
|
end
|
459
453
|
|
data/stdlib/set.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Portions Copyright (c) 2002-2013 Akinori MUSHA <knu@iDaemons.org>
|
2
|
-
class Set
|
3
|
-
include Enumerable
|
2
|
+
class ::Set
|
3
|
+
include ::Enumerable
|
4
4
|
|
5
5
|
def self.[](*ary)
|
6
6
|
new(ary)
|
@@ -10,7 +10,7 @@ class Set
|
|
10
10
|
@hash = {}
|
11
11
|
|
12
12
|
return if enum.nil?
|
13
|
-
raise ArgumentError, 'value must be enumerable' unless Enumerable === enum
|
13
|
+
::Kernel.raise ::ArgumentError, 'value must be enumerable' unless ::Enumerable === enum
|
14
14
|
|
15
15
|
if block
|
16
16
|
enum.each { |item| add yield(item) }
|
@@ -26,12 +26,11 @@ class Set
|
|
26
26
|
|
27
27
|
def -(enum)
|
28
28
|
unless enum.respond_to? :each
|
29
|
-
raise ArgumentError, 'value must be enumerable'
|
29
|
+
::Kernel.raise ::ArgumentError, 'value must be enumerable'
|
30
30
|
end
|
31
31
|
|
32
32
|
dup.subtract(enum)
|
33
33
|
end
|
34
|
-
alias difference -
|
35
34
|
|
36
35
|
def inspect
|
37
36
|
"#<Set: {#{to_a.join(',')}}>"
|
@@ -42,7 +41,7 @@ class Set
|
|
42
41
|
true
|
43
42
|
elsif other.instance_of?(self.class)
|
44
43
|
@hash == other.instance_variable_get(:@hash)
|
45
|
-
elsif other.is_a?(Set) && size == other.size
|
44
|
+
elsif other.is_a?(::Set) && size == other.size
|
46
45
|
other.all? { |o| @hash.include?(o) }
|
47
46
|
else
|
48
47
|
false
|
@@ -53,12 +52,11 @@ class Set
|
|
53
52
|
@hash[o] = true
|
54
53
|
self
|
55
54
|
end
|
56
|
-
alias << add
|
57
55
|
|
58
56
|
def classify(&block)
|
59
57
|
return enum_for(:classify) unless block_given?
|
60
58
|
|
61
|
-
result = Hash.new { |h, k| h[k] = self.class.new }
|
59
|
+
result = ::Hash.new { |h, k| h[k] = self.class.new }
|
62
60
|
|
63
61
|
each { |item| result[yield(item)].add item }
|
64
62
|
|
@@ -71,7 +69,6 @@ class Set
|
|
71
69
|
each { |item| result << yield(item) }
|
72
70
|
replace result
|
73
71
|
end
|
74
|
-
alias map! collect!
|
75
72
|
|
76
73
|
def delete(o)
|
77
74
|
@hash.delete(o)
|
@@ -113,8 +110,6 @@ class Set
|
|
113
110
|
size == before ? nil : self
|
114
111
|
end
|
115
112
|
|
116
|
-
alias filter! select!
|
117
|
-
|
118
113
|
def add?(o)
|
119
114
|
if include?(o)
|
120
115
|
nil
|
@@ -145,7 +140,6 @@ class Set
|
|
145
140
|
def include?(o)
|
146
141
|
@hash.include?(o)
|
147
142
|
end
|
148
|
-
alias member? include?
|
149
143
|
|
150
144
|
def merge(enum)
|
151
145
|
enum.each { |item| add item }
|
@@ -162,7 +156,6 @@ class Set
|
|
162
156
|
def size
|
163
157
|
@hash.size
|
164
158
|
end
|
165
|
-
alias length size
|
166
159
|
|
167
160
|
def subtract(enum)
|
168
161
|
enum.each { |item| delete item }
|
@@ -171,46 +164,43 @@ class Set
|
|
171
164
|
|
172
165
|
def |(enum)
|
173
166
|
unless enum.respond_to? :each
|
174
|
-
raise ArgumentError, 'value must be enumerable'
|
167
|
+
::Kernel.raise ::ArgumentError, 'value must be enumerable'
|
175
168
|
end
|
176
169
|
dup.merge(enum)
|
177
170
|
end
|
178
171
|
|
172
|
+
%x{
|
173
|
+
function is_set(set) {
|
174
|
+
#{`set`.is_a?(::Set) || ::Kernel.raise(::ArgumentError, 'value must be a set')}
|
175
|
+
}
|
176
|
+
}
|
177
|
+
|
179
178
|
def superset?(set)
|
180
|
-
|
179
|
+
`is_set(set)`
|
181
180
|
return false if size < set.size
|
182
181
|
set.all? { |o| include?(o) }
|
183
182
|
end
|
184
183
|
|
185
|
-
alias >= superset?
|
186
|
-
|
187
184
|
def proper_superset?(set)
|
188
|
-
|
185
|
+
`is_set(set)`
|
189
186
|
return false if size <= set.size
|
190
187
|
set.all? { |o| include?(o) }
|
191
188
|
end
|
192
189
|
|
193
|
-
alias > proper_superset?
|
194
|
-
|
195
190
|
def subset?(set)
|
196
|
-
|
191
|
+
`is_set(set)`
|
197
192
|
return false if set.size < size
|
198
193
|
all? { |o| set.include?(o) }
|
199
194
|
end
|
200
195
|
|
201
|
-
alias <= subset?
|
202
|
-
|
203
196
|
def proper_subset?(set)
|
204
|
-
|
197
|
+
`is_set(set)`
|
205
198
|
return false if set.size <= size
|
206
199
|
all? { |o| set.include?(o) }
|
207
200
|
end
|
208
201
|
|
209
|
-
alias < proper_subset?
|
210
|
-
|
211
202
|
def intersect?(set)
|
212
|
-
|
213
|
-
|
203
|
+
`is_set(set)`
|
214
204
|
if size < set.size
|
215
205
|
any? { |o| set.include?(o) }
|
216
206
|
else
|
@@ -222,15 +212,25 @@ class Set
|
|
222
212
|
!intersect?(set)
|
223
213
|
end
|
224
214
|
|
225
|
-
alias + |
|
226
|
-
alias union |
|
227
|
-
|
228
215
|
def to_a
|
229
216
|
@hash.keys
|
230
217
|
end
|
218
|
+
|
219
|
+
alias + |
|
220
|
+
alias < proper_subset?
|
221
|
+
alias << add
|
222
|
+
alias <= subset?
|
223
|
+
alias > proper_superset?
|
224
|
+
alias >= superset?
|
225
|
+
alias difference -
|
226
|
+
alias filter! select!
|
227
|
+
alias length size
|
228
|
+
alias map! collect!
|
229
|
+
alias member? include?
|
230
|
+
alias union |
|
231
231
|
end
|
232
232
|
|
233
|
-
module Enumerable
|
233
|
+
module ::Enumerable
|
234
234
|
def to_set(klass = Set, *args, &block)
|
235
235
|
klass.new(self, *args, &block)
|
236
236
|
end
|
@@ -0,0 +1,240 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
##
|
3
|
+
# == Manipulates strings like the UNIX Bourne shell
|
4
|
+
#
|
5
|
+
# This module manipulates strings according to the word parsing rules
|
6
|
+
# of the UNIX Bourne shell.
|
7
|
+
#
|
8
|
+
# The shellwords() function was originally a port of shellwords.pl,
|
9
|
+
# but modified to conform to the Shell & Utilities volume of the IEEE
|
10
|
+
# Std 1003.1-2008, 2016 Edition [1].
|
11
|
+
#
|
12
|
+
# === Usage
|
13
|
+
#
|
14
|
+
# You can use Shellwords to parse a string into a Bourne shell friendly Array.
|
15
|
+
#
|
16
|
+
# require 'shellwords'
|
17
|
+
#
|
18
|
+
# argv = Shellwords.split('three blind "mice"')
|
19
|
+
# argv #=> ["three", "blind", "mice"]
|
20
|
+
#
|
21
|
+
# Once you've required Shellwords, you can use the #split alias
|
22
|
+
# String#shellsplit.
|
23
|
+
#
|
24
|
+
# argv = "see how they run".shellsplit
|
25
|
+
# argv #=> ["see", "how", "they", "run"]
|
26
|
+
#
|
27
|
+
# They treat quotes as special characters, so an unmatched quote will
|
28
|
+
# cause an ArgumentError.
|
29
|
+
#
|
30
|
+
# argv = "they all ran after the farmer's wife".shellsplit
|
31
|
+
# #=> ArgumentError: Unmatched quote: ...
|
32
|
+
#
|
33
|
+
# Shellwords also provides methods that do the opposite.
|
34
|
+
# Shellwords.escape, or its alias, String#shellescape, escapes
|
35
|
+
# shell metacharacters in a string for use in a command line.
|
36
|
+
#
|
37
|
+
# filename = "special's.txt"
|
38
|
+
#
|
39
|
+
# system("cat -- #{filename.shellescape}")
|
40
|
+
# # runs "cat -- special\\'s.txt"
|
41
|
+
#
|
42
|
+
# Note the '--'. Without it, cat(1) will treat the following argument
|
43
|
+
# as a command line option if it starts with '-'. It is guaranteed
|
44
|
+
# that Shellwords.escape converts a string to a form that a Bourne
|
45
|
+
# shell will parse back to the original string, but it is the
|
46
|
+
# programmer's responsibility to make sure that passing an arbitrary
|
47
|
+
# argument to a command does no harm.
|
48
|
+
#
|
49
|
+
# Shellwords also comes with a core extension for Array, Array#shelljoin.
|
50
|
+
#
|
51
|
+
# dir = "Funny GIFs"
|
52
|
+
# argv = %W[ls -lta -- #{dir}]
|
53
|
+
# system(argv.shelljoin + " | less")
|
54
|
+
# # runs "ls -lta -- Funny\\ GIFs | less"
|
55
|
+
#
|
56
|
+
# You can use this method to build a complete command line out of an
|
57
|
+
# array of arguments.
|
58
|
+
#
|
59
|
+
# === Authors
|
60
|
+
# * Wakou Aoyama
|
61
|
+
# * Akinori MUSHA <knu@iDaemons.org>
|
62
|
+
#
|
63
|
+
# === Contact
|
64
|
+
# * Akinori MUSHA <knu@iDaemons.org> (current maintainer)
|
65
|
+
#
|
66
|
+
# === Resources
|
67
|
+
#
|
68
|
+
# 1: {IEEE Std 1003.1-2008, 2016 Edition, the Shell & Utilities volume}[http://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html]
|
69
|
+
|
70
|
+
module Shellwords
|
71
|
+
# Splits a string into an array of tokens in the same way the UNIX
|
72
|
+
# Bourne shell does.
|
73
|
+
#
|
74
|
+
# argv = Shellwords.split('here are "two words"')
|
75
|
+
# argv #=> ["here", "are", "two words"]
|
76
|
+
#
|
77
|
+
# Note, however, that this is not a command line parser. Shell
|
78
|
+
# metacharacters except for the single and double quotes and
|
79
|
+
# backslash are not treated as such.
|
80
|
+
#
|
81
|
+
# argv = Shellwords.split('ruby my_prog.rb | less')
|
82
|
+
# argv #=> ["ruby", "my_prog.rb", "|", "less"]
|
83
|
+
#
|
84
|
+
# String#shellsplit is a shortcut for this function.
|
85
|
+
#
|
86
|
+
# argv = 'here are "two words"'.shellsplit
|
87
|
+
# argv #=> ["here", "are", "two words"]
|
88
|
+
def shellsplit(line)
|
89
|
+
line += ' ' # Somehow this is needed for the JS regexp engine
|
90
|
+
words = []
|
91
|
+
field = String.new
|
92
|
+
line.scan(/\s*(?:([^\s\\\'\"]+)|'([^\']*)'|"((?:[^\"\\]|\\.)*)"|(\\.?)|(\S))(\r?\n?\Z|\s)?/m) do |(word, sq, dq, esc, garbage, sep)|
|
93
|
+
raise ArgumentError, "Unmatched quote: #{line.inspect}" if garbage
|
94
|
+
# 2.2.3 Double-Quotes:
|
95
|
+
#
|
96
|
+
# The <backslash> shall retain its special meaning as an
|
97
|
+
# escape character only when followed by one of the following
|
98
|
+
# characters when considered special:
|
99
|
+
#
|
100
|
+
# $ ` " \ <newline>
|
101
|
+
field += (word || sq || (dq && dq.gsub(/\\([$`"\\\n])/, '\\1')) || esc.gsub(/\\(.)/, '\\1'))
|
102
|
+
if sep
|
103
|
+
words << field
|
104
|
+
field = String.new
|
105
|
+
end
|
106
|
+
end
|
107
|
+
words
|
108
|
+
end
|
109
|
+
|
110
|
+
alias shellwords shellsplit
|
111
|
+
|
112
|
+
module_function :shellsplit, :shellwords
|
113
|
+
|
114
|
+
class << self
|
115
|
+
alias split shellsplit
|
116
|
+
end
|
117
|
+
|
118
|
+
# Escapes a string so that it can be safely used in a Bourne shell
|
119
|
+
# command line. +str+ can be a non-string object that responds to
|
120
|
+
# +to_s+.
|
121
|
+
#
|
122
|
+
# Note that a resulted string should be used unquoted and is not
|
123
|
+
# intended for use in double quotes nor in single quotes.
|
124
|
+
#
|
125
|
+
# argv = Shellwords.escape("It's better to give than to receive")
|
126
|
+
# argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"
|
127
|
+
#
|
128
|
+
# String#shellescape is a shorthand for this function.
|
129
|
+
#
|
130
|
+
# argv = "It's better to give than to receive".shellescape
|
131
|
+
# argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"
|
132
|
+
#
|
133
|
+
# # Search files in lib for method definitions
|
134
|
+
# pattern = "^[ \t]*def "
|
135
|
+
# open("| grep -Ern -e #{pattern.shellescape} lib") { |grep|
|
136
|
+
# grep.each_line { |line|
|
137
|
+
# file, lineno, matched_line = line.split(':', 3)
|
138
|
+
# # ...
|
139
|
+
# }
|
140
|
+
# }
|
141
|
+
#
|
142
|
+
# It is the caller's responsibility to encode the string in the right
|
143
|
+
# encoding for the shell environment where this string is used.
|
144
|
+
#
|
145
|
+
# Multibyte characters are treated as multibyte characters, not as bytes.
|
146
|
+
#
|
147
|
+
# Returns an empty quoted String if +str+ has a length of zero.
|
148
|
+
def shellescape(str)
|
149
|
+
str = str.to_s
|
150
|
+
|
151
|
+
# An empty argument will be skipped, so return empty quotes.
|
152
|
+
return "''".dup if str.empty?
|
153
|
+
|
154
|
+
str = str.dup
|
155
|
+
|
156
|
+
# Treat multibyte characters as is. It is the caller's responsibility
|
157
|
+
# to encode the string in the right encoding for the shell
|
158
|
+
# environment.
|
159
|
+
str = str.gsub(/[^A-Za-z0-9_\-.,:+\/@\n]/, '\\\\\\&')
|
160
|
+
|
161
|
+
# A LF cannot be escaped with a backslash because a backslash + LF
|
162
|
+
# combo is regarded as a line continuation and simply ignored.
|
163
|
+
str = str.gsub(/\n/, "'\n'")
|
164
|
+
|
165
|
+
str
|
166
|
+
end
|
167
|
+
|
168
|
+
module_function :shellescape
|
169
|
+
|
170
|
+
class << self
|
171
|
+
alias escape shellescape
|
172
|
+
end
|
173
|
+
|
174
|
+
# Builds a command line string from an argument list, +array+.
|
175
|
+
#
|
176
|
+
# All elements are joined into a single string with fields separated by a
|
177
|
+
# space, where each element is escaped for the Bourne shell and stringified
|
178
|
+
# using +to_s+.
|
179
|
+
#
|
180
|
+
# ary = ["There's", "a", "time", "and", "place", "for", "everything"]
|
181
|
+
# argv = Shellwords.join(ary)
|
182
|
+
# argv #=> "There\\'s a time and place for everything"
|
183
|
+
#
|
184
|
+
# Array#shelljoin is a shortcut for this function.
|
185
|
+
#
|
186
|
+
# ary = ["Don't", "rock", "the", "boat"]
|
187
|
+
# argv = ary.shelljoin
|
188
|
+
# argv #=> "Don\\'t rock the boat"
|
189
|
+
#
|
190
|
+
# You can also mix non-string objects in the elements as allowed in Array#join.
|
191
|
+
#
|
192
|
+
# output = `#{['ps', '-p', $$].shelljoin}`
|
193
|
+
#
|
194
|
+
def shelljoin(array)
|
195
|
+
array.map { |arg| shellescape(arg) }.join(' ')
|
196
|
+
end
|
197
|
+
|
198
|
+
module_function :shelljoin
|
199
|
+
|
200
|
+
class << self
|
201
|
+
alias join shelljoin
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
class String
|
206
|
+
# call-seq:
|
207
|
+
# str.shellsplit => array
|
208
|
+
#
|
209
|
+
# Splits +str+ into an array of tokens in the same way the UNIX
|
210
|
+
# Bourne shell does.
|
211
|
+
#
|
212
|
+
# See Shellwords.shellsplit for details.
|
213
|
+
def shellsplit
|
214
|
+
Shellwords.split(self)
|
215
|
+
end
|
216
|
+
|
217
|
+
# call-seq:
|
218
|
+
# str.shellescape => string
|
219
|
+
#
|
220
|
+
# Escapes +str+ so that it can be safely used in a Bourne shell
|
221
|
+
# command line.
|
222
|
+
#
|
223
|
+
# See Shellwords.shellescape for details.
|
224
|
+
def shellescape
|
225
|
+
Shellwords.escape(self)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
class Array
|
230
|
+
# call-seq:
|
231
|
+
# array.shelljoin => string
|
232
|
+
#
|
233
|
+
# Builds a command line string from an argument list +array+ joining
|
234
|
+
# all elements escaped for the Bourne shell and separated by a space.
|
235
|
+
#
|
236
|
+
# See Shellwords.shelljoin for details.
|
237
|
+
def shelljoin
|
238
|
+
Shellwords.join(self)
|
239
|
+
end
|
240
|
+
end
|
data/stdlib/stringio.rb
CHANGED
@@ -22,8 +22,6 @@ class StringIO < IO
|
|
22
22
|
@position == @string.length
|
23
23
|
end
|
24
24
|
|
25
|
-
alias eof eof?
|
26
|
-
|
27
25
|
def seek(pos, whence = IO::SEEK_SET)
|
28
26
|
# Let's reset the read buffer, because it will be most likely wrong
|
29
27
|
@read_buffer = ''
|
@@ -56,10 +54,6 @@ class StringIO < IO
|
|
56
54
|
@position
|
57
55
|
end
|
58
56
|
|
59
|
-
alias pos tell
|
60
|
-
|
61
|
-
alias pos= seek
|
62
|
-
|
63
57
|
def rewind
|
64
58
|
seek 0
|
65
59
|
end
|
@@ -113,5 +107,8 @@ class StringIO < IO
|
|
113
107
|
read(length)
|
114
108
|
end
|
115
109
|
|
110
|
+
alias eof eof?
|
111
|
+
alias pos tell
|
112
|
+
alias pos= seek
|
116
113
|
alias readpartial read
|
117
114
|
end
|