Skip to content

Commit ffe835a

Browse files
author
webdev778
committed
On Windows platform Enumerable#sort_by is non-deterministic. This patch ensures a correct behaviour.
1 parent accd27d commit ffe835a

File tree

4 files changed

+12
-3
lines changed

4 files changed

+12
-3
lines changed

ruby/lib/interscript/compiler/javascript.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def compile_rule(r, map = @map, wrapper = false)
8686
rescue
8787
# Otherwise let's build a megaregexp
8888
a = []
89-
r.children.sort_by{ |rule| -rule.max_length }.each do |i|
89+
Interscript::Stdlib.deterministic_sort_by_max_length(r.children).each do |i|
9090
raise ArgumentError, "Can't parallelize #{i.class}" unless Interscript::Node::Rule::Sub === i
9191

9292
a << [build_regexp(i, map), compile_item(i.to, map, :parstr)]

ruby/lib/interscript/compiler/ruby.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def compile_rule(r, map = @map, wrapper = false)
7676
rescue
7777
# Otherwise let's build a megaregexp
7878
a = []
79-
r.children.sort_by{ |rule| -rule.max_length }.each do |i|
79+
Interscript::Stdlib.deterministic_sort_by_max_length(r.children).each do |i|
8080
raise ArgumentError, "Can't parallelize #{i.class}" unless Interscript::Node::Rule::Sub === i
8181

8282
a << [build_regexp(i, map), compile_item(i.to, map, :parstr)]

ruby/lib/interscript/interpreter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def execute_rule r
4747
$using_tree = false
4848
# Otherwise let's build a megaregexp
4949
subs_array = []
50-
r.children.sort_by{ |rule| -rule.max_length }.each do |i| # rule.from.max_length gives somewhat better test results, why is that
50+
Interscript::Stdlib.deterministic_sort_by_max_length(r.children).each do |i| # rule.from.max_length gives somewhat better test results, why is that
5151
raise ArgumentError, "Can't parallelize #{i.class}" unless Interscript::Node::Rule::Sub === i
5252

5353
subs_array << [build_regexp(i), build_item(i.to, :parstr)]

ruby/lib/interscript/stdlib.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,15 @@ def self.parallel_replace(str, hash)
157157
parallel_replace_tree(str, tree)
158158
end
159159

160+
# On Windows at least, sort_by is non-deterministic. Let's add some determinism
161+
# to our efforts.
162+
def self.deterministic_sort_by_max_length(ary)
163+
# Deterministic on Linux:
164+
# ary.sort_by{ |rule| -rule.max_length }
165+
166+
ary.each_with_index.sort_by{ |rule,idx| -rule.max_length*100000 + idx }.map(&:first)
167+
end
168+
160169
def self.available_functions
161170
%i[title_case downcase compose decompose separate secryst]
162171
end

0 commit comments

Comments
 (0)