rexml 3.2.1 → 3.2.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rexml might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/NEWS.md +18 -0
- data/lib/rexml/functions.rb +26 -23
- data/lib/rexml/rexml.rb +1 -1
- data/lib/rexml/xpath_parser.rb +149 -113
- data/rexml.gemspec +0 -1
- metadata +2 -3
- data/lib/rexml/syncenumerator.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80a799893d66ff50bf8f93d6278b7243d29f1fcdc9d3e1b34ddbb3d044e288c8
|
4
|
+
data.tar.gz: c78162208507f9aa9dfbb7596d39fc3afbc99d244837b70b96f8477470ce7cc0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0a6d3cd983aff3f4427dfa6e50e06b9720e2b704c55133d99ce9b7e81daeca038a5464341df81ada5322bf16b60c38e40d5301d90a659ed8a2a983db074e132
|
7
|
+
data.tar.gz: e261132e4c5389c0ac9f489f5dda410c4980b75a27166329faf94b316d966ff73e6dc1e79ee131270efbf52209924db193973cf22ea8e9e204039ca8773fa8fa
|
data/NEWS.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# News
|
2
2
|
|
3
|
+
## 3.2.2 - 2019-06-03 {#version-3-2-2}
|
4
|
+
|
5
|
+
### Fixes
|
6
|
+
|
7
|
+
* xpath: Fixed a bug for equality and relational expressions.
|
8
|
+
[GitHub#17][Reported by Mirko Budszuhn]
|
9
|
+
|
10
|
+
* xpath: Fixed `boolean()` implementation.
|
11
|
+
|
12
|
+
* xpath: Fixed `local_name()` with nonexistent node.
|
13
|
+
|
14
|
+
* xpath: Fixed `number()` implementation with node set.
|
15
|
+
[GitHub#18][Reported by Mirko Budszuhn]
|
16
|
+
|
17
|
+
### Thanks
|
18
|
+
|
19
|
+
* Mirko Budszuhn
|
20
|
+
|
3
21
|
## 3.2.1 - 2019-05-04 {#version-3-2-1}
|
4
22
|
|
5
23
|
### Improvements
|
data/lib/rexml/functions.rb
CHANGED
@@ -66,11 +66,11 @@ module REXML
|
|
66
66
|
def Functions::id( object )
|
67
67
|
end
|
68
68
|
|
69
|
-
|
70
|
-
|
71
|
-
get_namespace( node_set ) do |node|
|
69
|
+
def Functions::local_name(node_set=nil)
|
70
|
+
get_namespace(node_set) do |node|
|
72
71
|
return node.local_name
|
73
72
|
end
|
73
|
+
""
|
74
74
|
end
|
75
75
|
|
76
76
|
def Functions::namespace_uri( node_set=nil )
|
@@ -315,18 +315,23 @@ module REXML
|
|
315
315
|
end
|
316
316
|
end
|
317
317
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
318
|
+
def Functions::boolean(object=@@context[:node])
|
319
|
+
case object
|
320
|
+
when true, false
|
321
|
+
object
|
322
|
+
when Float
|
323
|
+
return false if object.zero?
|
324
|
+
return false if object.nan?
|
325
|
+
true
|
326
|
+
when Numeric
|
327
|
+
not object.zero?
|
328
|
+
when String
|
329
|
+
not object.empty?
|
330
|
+
when Array
|
331
|
+
not object.empty?
|
332
|
+
else
|
333
|
+
object ? true : false
|
328
334
|
end
|
329
|
-
return object ? true : false
|
330
335
|
end
|
331
336
|
|
332
337
|
# UNTESTED
|
@@ -380,25 +385,23 @@ module REXML
|
|
380
385
|
#
|
381
386
|
# an object of a type other than the four basic types is converted to a
|
382
387
|
# number in a way that is dependent on that type
|
383
|
-
def Functions::number(
|
384
|
-
object = @@context[:node] unless object
|
388
|
+
def Functions::number(object=@@context[:node])
|
385
389
|
case object
|
386
390
|
when true
|
387
391
|
Float(1)
|
388
392
|
when false
|
389
393
|
Float(0)
|
390
394
|
when Array
|
391
|
-
number(string(
|
395
|
+
number(string(object))
|
392
396
|
when Numeric
|
393
397
|
object.to_f
|
394
398
|
else
|
395
|
-
str = string(
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
str.to_f
|
399
|
+
str = string(object)
|
400
|
+
case str.strip
|
401
|
+
when /\A\s*(-?(?:\d+(?:\.\d*)?|\.\d+))\s*\z/
|
402
|
+
$1.to_f
|
400
403
|
else
|
401
|
-
|
404
|
+
Float::NAN
|
402
405
|
end
|
403
406
|
end
|
404
407
|
end
|
data/lib/rexml/rexml.rb
CHANGED
data/lib/rexml/xpath_parser.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require "pp"
|
4
|
+
|
2
5
|
require_relative 'namespace'
|
3
6
|
require_relative 'xmltokens'
|
4
7
|
require_relative 'attribute'
|
5
|
-
require_relative 'syncenumerator'
|
6
8
|
require_relative 'parsers/xpathparser'
|
7
9
|
|
8
10
|
class Object
|
@@ -47,7 +49,10 @@ module REXML
|
|
47
49
|
include XMLTokens
|
48
50
|
LITERAL = /^'([^']*)'|^"([^"]*)"/u
|
49
51
|
|
52
|
+
DEBUG = (ENV["REXML_XPATH_PARSER_DEBUG"] == "true")
|
53
|
+
|
50
54
|
def initialize(strict: false)
|
55
|
+
@debug = DEBUG
|
51
56
|
@parser = REXML::Parsers::XPathParser.new
|
52
57
|
@namespaces = nil
|
53
58
|
@variables = {}
|
@@ -135,7 +140,7 @@ module REXML
|
|
135
140
|
when Array # nodeset
|
136
141
|
unnode(result)
|
137
142
|
else
|
138
|
-
result
|
143
|
+
[result]
|
139
144
|
end
|
140
145
|
end
|
141
146
|
|
@@ -162,10 +167,10 @@ module REXML
|
|
162
167
|
# Expr takes a stack of path elements and a set of nodes (either a Parent
|
163
168
|
# or an Array and returns an Array of matching nodes
|
164
169
|
def expr( path_stack, nodeset, context=nil )
|
165
|
-
|
170
|
+
enter(:expr, path_stack, nodeset) if @debug
|
166
171
|
return nodeset if path_stack.length == 0 || nodeset.length == 0
|
167
172
|
while path_stack.length > 0
|
168
|
-
|
173
|
+
trace(:while, path_stack, nodeset) if @debug
|
169
174
|
if nodeset.length == 0
|
170
175
|
path_stack.clear
|
171
176
|
return []
|
@@ -184,7 +189,7 @@ module REXML
|
|
184
189
|
child(nodeset)
|
185
190
|
end
|
186
191
|
when :literal
|
187
|
-
|
192
|
+
trace(:literal, path_stack, nodeset) if @debug
|
188
193
|
return path_stack.shift
|
189
194
|
when :attribute
|
190
195
|
nodeset = step(path_stack, any_type: :attribute) do
|
@@ -335,26 +340,24 @@ module REXML
|
|
335
340
|
var_name = path_stack.shift
|
336
341
|
return [@variables[var_name]]
|
337
342
|
|
338
|
-
|
339
|
-
# TODO: Special case for :or and :and -- not evaluate the right
|
340
|
-
# operand if the left alone determines result (i.e. is true for
|
341
|
-
# :or and false for :and).
|
342
|
-
when :eq, :neq, :lt, :lteq, :gt, :gteq, :or
|
343
|
+
when :eq, :neq, :lt, :lteq, :gt, :gteq
|
343
344
|
left = expr( path_stack.shift, nodeset.dup, context )
|
344
345
|
right = expr( path_stack.shift, nodeset.dup, context )
|
345
346
|
res = equality_relational_compare( left, op, right )
|
346
|
-
|
347
|
+
trace(op, left, right, res) if @debug
|
347
348
|
return res
|
348
349
|
|
350
|
+
when :or
|
351
|
+
left = expr(path_stack.shift, nodeset.dup, context)
|
352
|
+
return true if Functions.boolean(left)
|
353
|
+
right = expr(path_stack.shift, nodeset.dup, context)
|
354
|
+
return Functions.boolean(right)
|
355
|
+
|
349
356
|
when :and
|
350
|
-
left = expr(
|
351
|
-
return
|
352
|
-
|
353
|
-
|
354
|
-
end
|
355
|
-
right = expr( path_stack.shift, nodeset.dup, context )
|
356
|
-
res = equality_relational_compare( left, op, right )
|
357
|
-
return res
|
357
|
+
left = expr(path_stack.shift, nodeset.dup, context)
|
358
|
+
return false unless Functions.boolean(left)
|
359
|
+
right = expr(path_stack.shift, nodeset.dup, context)
|
360
|
+
return Functions.boolean(right)
|
358
361
|
|
359
362
|
when :div, :mod, :mult, :plus, :minus
|
360
363
|
left = expr(path_stack.shift, nodeset, context)
|
@@ -391,45 +394,48 @@ module REXML
|
|
391
394
|
when :function
|
392
395
|
func_name = path_stack.shift.tr('-','_')
|
393
396
|
arguments = path_stack.shift
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
result
|
397
|
+
|
398
|
+
if nodeset.size != 1
|
399
|
+
message = "[BUG] Node set size must be 1 for function call: "
|
400
|
+
message += "<#{func_name}>: <#{nodeset.inspect}>: "
|
401
|
+
message += "<#{arguments.inspect}>"
|
402
|
+
raise message
|
403
|
+
end
|
404
|
+
|
405
|
+
node = nodeset.first
|
406
|
+
if context
|
407
|
+
target_context = context
|
408
|
+
else
|
409
|
+
target_context = {:size => nodeset.size}
|
410
|
+
if node.is_a?(XPathNode)
|
411
|
+
target_context[:node] = node.raw_node
|
412
|
+
target_context[:index] = node.position
|
413
|
+
else
|
414
|
+
target_context[:node] = node
|
415
|
+
target_context[:index] = 1
|
414
416
|
end
|
415
|
-
Functions.context = cont
|
416
|
-
res << Functions.send( func_name, *args )
|
417
417
|
end
|
418
|
-
|
418
|
+
args = arguments.dclone.collect do |arg|
|
419
|
+
result = expr(arg, nodeset, target_context)
|
420
|
+
result = unnode(result) if result.is_a?(Array)
|
421
|
+
result
|
422
|
+
end
|
423
|
+
Functions.context = target_context
|
424
|
+
return Functions.send(func_name, *args)
|
419
425
|
|
420
426
|
else
|
421
427
|
raise "[BUG] Unexpected path: <#{op.inspect}>: <#{path_stack.inspect}>"
|
422
428
|
end
|
423
429
|
end # while
|
424
430
|
return nodeset
|
425
|
-
|
426
|
-
|
431
|
+
ensure
|
432
|
+
leave(:expr, path_stack, nodeset) if @debug
|
427
433
|
end
|
428
434
|
|
429
435
|
def step(path_stack, any_type: :element, order: :forward)
|
430
436
|
nodesets = yield
|
431
437
|
begin
|
432
|
-
|
438
|
+
enter(:step, path_stack, nodesets) if @debug
|
433
439
|
nodesets = node_test(path_stack, nodesets, any_type: any_type)
|
434
440
|
while path_stack[0] == :predicate
|
435
441
|
path_stack.shift # :predicate
|
@@ -457,13 +463,13 @@ module REXML
|
|
457
463
|
new_nodeset << XPathNode.new(node, position: new_nodeset.size + 1)
|
458
464
|
end
|
459
465
|
new_nodeset
|
460
|
-
|
461
|
-
|
466
|
+
ensure
|
467
|
+
leave(:step, path_stack, new_nodeset) if @debug
|
462
468
|
end
|
463
469
|
end
|
464
470
|
|
465
471
|
def node_test(path_stack, nodesets, any_type: :element)
|
466
|
-
|
472
|
+
enter(:node_test, path_stack, nodesets) if @debug
|
467
473
|
operator = path_stack.shift
|
468
474
|
case operator
|
469
475
|
when :qname
|
@@ -563,8 +569,8 @@ module REXML
|
|
563
569
|
raise message
|
564
570
|
end
|
565
571
|
new_nodesets
|
566
|
-
|
567
|
-
|
572
|
+
ensure
|
573
|
+
leave(:node_test, path_stack, new_nodesets) if @debug
|
568
574
|
end
|
569
575
|
|
570
576
|
def filter_nodeset(nodeset)
|
@@ -577,7 +583,7 @@ module REXML
|
|
577
583
|
end
|
578
584
|
|
579
585
|
def evaluate_predicate(expression, nodesets)
|
580
|
-
|
586
|
+
enter(:predicate, expression, nodesets) if @debug
|
581
587
|
new_nodesets = nodesets.collect do |nodeset|
|
582
588
|
new_nodeset = []
|
583
589
|
subcontext = { :size => nodeset.size }
|
@@ -590,7 +596,7 @@ module REXML
|
|
590
596
|
subcontext[:index] = index + 1
|
591
597
|
end
|
592
598
|
result = expr(expression.dclone, [node], subcontext)
|
593
|
-
|
599
|
+
trace(:predicate_evaluate, expression, node, subcontext, result) if @debug
|
594
600
|
result = result[0] if result.kind_of? Array and result.length == 1
|
595
601
|
if result.kind_of? Numeric
|
596
602
|
if result == node.position
|
@@ -611,13 +617,15 @@ module REXML
|
|
611
617
|
new_nodeset
|
612
618
|
end
|
613
619
|
new_nodesets
|
614
|
-
|
615
|
-
|
620
|
+
ensure
|
621
|
+
leave(:predicate, new_nodesets) if @debug
|
616
622
|
end
|
617
623
|
|
618
624
|
def trace(*args)
|
619
625
|
indent = " " * @nest
|
620
|
-
|
626
|
+
PP.pp(args, "").each_line do |line|
|
627
|
+
puts("#{indent}#{line}")
|
628
|
+
end
|
621
629
|
end
|
622
630
|
|
623
631
|
def enter(tag, *args)
|
@@ -798,31 +806,28 @@ module REXML
|
|
798
806
|
end
|
799
807
|
end
|
800
808
|
|
801
|
-
def equality_relational_compare(
|
809
|
+
def equality_relational_compare(set1, op, set2)
|
802
810
|
set1 = unnode(set1) if set1.is_a?(Array)
|
803
811
|
set2 = unnode(set2) if set2.is_a?(Array)
|
812
|
+
|
804
813
|
if set1.kind_of? Array and set2.kind_of? Array
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
res << compare( i1, op, i2 )
|
815
|
-
}
|
816
|
-
return res
|
814
|
+
# If both objects to be compared are node-sets, then the
|
815
|
+
# comparison will be true if and only if there is a node in the
|
816
|
+
# first node-set and a node in the second node-set such that the
|
817
|
+
# result of performing the comparison on the string-values of
|
818
|
+
# the two nodes is true.
|
819
|
+
set1.product(set2).any? do |node1, node2|
|
820
|
+
node_string1 = Functions.string(node1)
|
821
|
+
node_string2 = Functions.string(node2)
|
822
|
+
compare(node_string1, op, node_string2)
|
817
823
|
end
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
if set1.kind_of? Array or set2.kind_of? Array
|
824
|
+
elsif set1.kind_of? Array or set2.kind_of? Array
|
825
|
+
# If one is nodeset and other is number, compare number to each item
|
826
|
+
# in nodeset s.t. number op number(string(item))
|
827
|
+
# If one is nodeset and other is string, compare string to each item
|
828
|
+
# in nodeset s.t. string op string(item)
|
829
|
+
# If one is nodeset and other is boolean, compare boolean to each item
|
830
|
+
# in nodeset s.t. boolean op boolean(item)
|
826
831
|
if set1.kind_of? Array
|
827
832
|
a = set1
|
828
833
|
b = set2
|
@@ -833,15 +838,23 @@ module REXML
|
|
833
838
|
|
834
839
|
case b
|
835
840
|
when true, false
|
836
|
-
|
841
|
+
each_unnode(a).any? do |unnoded|
|
842
|
+
compare(Functions.boolean(unnoded), op, b)
|
843
|
+
end
|
837
844
|
when Numeric
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
845
|
+
each_unnode(a).any? do |unnoded|
|
846
|
+
compare(Functions.number(unnoded), op, b)
|
847
|
+
end
|
848
|
+
when /\A\d+(\.\d+)?\z/
|
849
|
+
b = Functions.number(b)
|
850
|
+
each_unnode(a).any? do |unnoded|
|
851
|
+
compare(Functions.number(unnoded), op, b)
|
852
|
+
end
|
842
853
|
else
|
843
|
-
b = Functions::string(
|
844
|
-
|
854
|
+
b = Functions::string(b)
|
855
|
+
each_unnode(a).any? do |unnoded|
|
856
|
+
compare(Functions::string(unnoded), op, b)
|
857
|
+
end
|
845
858
|
end
|
846
859
|
else
|
847
860
|
# If neither is nodeset,
|
@@ -851,34 +864,52 @@ module REXML
|
|
851
864
|
# Else, convert to string
|
852
865
|
# Else
|
853
866
|
# Convert both to numbers and compare
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
867
|
+
compare(set1, op, set2)
|
868
|
+
end
|
869
|
+
end
|
870
|
+
|
871
|
+
def value_type(value)
|
872
|
+
case value
|
873
|
+
when true, false
|
874
|
+
:boolean
|
875
|
+
when Numeric
|
876
|
+
:number
|
877
|
+
when String
|
878
|
+
:string
|
879
|
+
else
|
880
|
+
raise "[BUG] Unexpected value type: <#{value.inspect}>"
|
881
|
+
end
|
882
|
+
end
|
883
|
+
|
884
|
+
def normalize_compare_values(a, operator, b)
|
885
|
+
a_type = value_type(a)
|
886
|
+
b_type = value_type(b)
|
887
|
+
case operator
|
888
|
+
when :eq, :neq
|
889
|
+
if a_type == :boolean or b_type == :boolean
|
890
|
+
a = Functions.boolean(a) unless a_type == :boolean
|
891
|
+
b = Functions.boolean(b) unless b_type == :boolean
|
892
|
+
elsif a_type == :number or b_type == :number
|
893
|
+
a = Functions.number(a) unless a_type == :number
|
894
|
+
b = Functions.number(b) unless b_type == :number
|
861
895
|
else
|
862
|
-
|
863
|
-
|
864
|
-
set1 = Functions::number( s1 )
|
865
|
-
set2 = Functions::number( s2 )
|
866
|
-
else
|
867
|
-
set1 = Functions::string( set1 )
|
868
|
-
set2 = Functions::string( set2 )
|
869
|
-
end
|
870
|
-
else
|
871
|
-
set1 = Functions::number( set1 )
|
872
|
-
set2 = Functions::number( set2 )
|
873
|
-
end
|
896
|
+
a = Functions.string(a) unless a_type == :string
|
897
|
+
b = Functions.string(b) unless b_type == :string
|
874
898
|
end
|
875
|
-
|
899
|
+
when :lt, :lteq, :gt, :gteq
|
900
|
+
a = Functions.number(a) unless a_type == :number
|
901
|
+
b = Functions.number(b) unless b_type == :number
|
902
|
+
else
|
903
|
+
message = "[BUG] Unexpected compare operator: " +
|
904
|
+
"<#{operator.inspect}>: <#{a.inspect}>: <#{b.inspect}>"
|
905
|
+
raise message
|
876
906
|
end
|
877
|
-
|
907
|
+
[a, b]
|
878
908
|
end
|
879
909
|
|
880
|
-
def compare
|
881
|
-
|
910
|
+
def compare(a, operator, b)
|
911
|
+
a, b = normalize_compare_values(a, operator, b)
|
912
|
+
case operator
|
882
913
|
when :eq
|
883
914
|
a == b
|
884
915
|
when :neq
|
@@ -891,22 +922,27 @@ module REXML
|
|
891
922
|
a > b
|
892
923
|
when :gteq
|
893
924
|
a >= b
|
894
|
-
when :and
|
895
|
-
a and b
|
896
|
-
when :or
|
897
|
-
a or b
|
898
925
|
else
|
899
|
-
|
926
|
+
message = "[BUG] Unexpected compare operator: " +
|
927
|
+
"<#{operator.inspect}>: <#{a.inspect}>: <#{b.inspect}>"
|
928
|
+
raise message
|
900
929
|
end
|
901
930
|
end
|
902
931
|
|
903
|
-
def
|
904
|
-
nodeset
|
932
|
+
def each_unnode(nodeset)
|
933
|
+
return to_enum(__method__, nodeset) unless block_given?
|
934
|
+
nodeset.each do |node|
|
905
935
|
if node.is_a?(XPathNode)
|
906
936
|
unnoded = node.raw_node
|
907
937
|
else
|
908
938
|
unnoded = node
|
909
939
|
end
|
940
|
+
yield(unnoded)
|
941
|
+
end
|
942
|
+
end
|
943
|
+
|
944
|
+
def unnode(nodeset)
|
945
|
+
each_unnode(nodeset).collect do |unnoded|
|
910
946
|
unnoded = yield(unnoded) if block_given?
|
911
947
|
unnoded
|
912
948
|
end
|
data/rexml.gemspec
CHANGED
@@ -64,7 +64,6 @@ Gem::Specification.new do |spec|
|
|
64
64
|
"lib/rexml/security.rb",
|
65
65
|
"lib/rexml/source.rb",
|
66
66
|
"lib/rexml/streamlistener.rb",
|
67
|
-
"lib/rexml/syncenumerator.rb",
|
68
67
|
"lib/rexml/text.rb",
|
69
68
|
"lib/rexml/undefinednamespaceexception.rb",
|
70
69
|
"lib/rexml/validation/relaxng.rb",
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rexml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kouhei Sutou
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -92,7 +92,6 @@ files:
|
|
92
92
|
- lib/rexml/security.rb
|
93
93
|
- lib/rexml/source.rb
|
94
94
|
- lib/rexml/streamlistener.rb
|
95
|
-
- lib/rexml/syncenumerator.rb
|
96
95
|
- lib/rexml/text.rb
|
97
96
|
- lib/rexml/undefinednamespaceexception.rb
|
98
97
|
- lib/rexml/validation/relaxng.rb
|
data/lib/rexml/syncenumerator.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: false
|
2
|
-
module REXML
|
3
|
-
class SyncEnumerator
|
4
|
-
include Enumerable
|
5
|
-
|
6
|
-
# Creates a new SyncEnumerator which enumerates rows of given
|
7
|
-
# Enumerable objects.
|
8
|
-
def initialize(*enums)
|
9
|
-
@gens = enums
|
10
|
-
@length = @gens.collect {|x| x.size }.max
|
11
|
-
end
|
12
|
-
|
13
|
-
# Returns the number of enumerated Enumerable objects, i.e. the size
|
14
|
-
# of each row.
|
15
|
-
def size
|
16
|
-
@gens.size
|
17
|
-
end
|
18
|
-
|
19
|
-
# Returns the number of enumerated Enumerable objects, i.e. the size
|
20
|
-
# of each row.
|
21
|
-
def length
|
22
|
-
@gens.length
|
23
|
-
end
|
24
|
-
|
25
|
-
# Enumerates rows of the Enumerable objects.
|
26
|
-
def each
|
27
|
-
@length.times {|i|
|
28
|
-
yield @gens.collect {|x| x[i]}
|
29
|
-
}
|
30
|
-
self
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|