persistent-dmnd 2.0.5 → 3.0.0
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.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +27 -312
- data/.standard.yml +4 -0
- data/CODE_OF_CONDUCT.adoc +99 -45
- data/README.adoc +17 -17
- data/Rakefile +4 -3
- data/UPSTREAM_TODO.adoc +0 -10
- data/gems.rb +1 -4
- data/lib/persistent-dmnd.rb +0 -3
- data/lib/persistent-/360/237/222/216.rb +1 -7
- data/lib/persistent_dmnd/array.rb +5 -10
- data/lib/persistent_dmnd/concurrent_ruby_support.rb +1 -6
- data/lib/persistent_dmnd/dmndifier.rb +17 -19
- data/lib/persistent_dmnd/everywhere.rb +1 -3
- data/lib/persistent_dmnd/hash.rb +5 -30
- data/lib/persistent_dmnd/is_persistent.rb +0 -3
- data/lib/persistent_dmnd/jruby_9_2_set_workaround.rb +32 -32
- data/lib/persistent_dmnd/self_conversion.rb +0 -7
- data/lib/persistent_dmnd/set.rb +9 -12
- data/lib/persistent_dmnd/version.rb +1 -4
- data/persistent-dmnd.gemspec +11 -15
- metadata +25 -35
- data/.ruby-version +0 -1
- data/lib/persistent_dmnd/jruby_workaround.rb +0 -107
- data/lib/persistent_dmnd/ruby_1_9_and_2_0_support.rb +0 -48
- data/sorbet/config +0 -2
- data/sorbet/rbi/gems/concurrent-ruby.rbi +0 -1660
- data/sorbet/rbi/gems/hamster.rbi +0 -683
- data/sorbet/rbi/hidden-definitions/errors.txt +0 -2552
- data/sorbet/rbi/hidden-definitions/hidden.rbi +0 -4180
- data/sorbet/rbi/sorbet-typed/lib/rake/all/rake.rbi +0 -645
- data/sorbet/rbi/sorbet-typed/lib/rspec-core/all/rspec-core.rbi +0 -1891
- data/sorbet/rbi/todo.rbi +0 -10
data/README.adoc
CHANGED
|
@@ -94,10 +94,10 @@ Beyond being immutable, these data structures are thread-safe, and can be effici
|
|
|
94
94
|
|
|
95
95
|
It also (_optionally!_) interoperates with the https://github.com/ruby-concurrency/concurrent-ruby[concurrent-ruby gem], for when you need that extra Oomph (or just thread-safe mutability). See <<concurrent-ruby-interoperability,below>> for more details.
|
|
96
96
|
|
|
97
|
-
Underneath the covers, persistent-💎 mostly builds atop the awesome https://github.com/
|
|
97
|
+
Underneath the covers, persistent-💎 mostly builds atop the awesome https://github.com/immutable-ruby/immutable-ruby[immutable-ruby gem].
|
|
98
98
|
Big thanks to its equally-awesome authors!
|
|
99
99
|
|
|
100
|
-
Persistent-💎 is fully supported and tested on Ruby versions
|
|
100
|
+
Persistent-💎 is fully supported and tested on Ruby versions 2.4 to 3.3, JRuby 9.2 to 9.4, and TruffleRuby 🎉.
|
|
101
101
|
If we don't support your Ruby, it's probably a Python binary instead (or a potato?).
|
|
102
102
|
Keep calm and 💎 away!
|
|
103
103
|
|
|
@@ -258,11 +258,11 @@ my_set = Set.new([:regular, :ruby, :set])
|
|
|
258
258
|
=> Persistent💎::Set[:regular, :ruby, :set]
|
|
259
259
|
----
|
|
260
260
|
|
|
261
|
-
And it works for https://github.com/hamstergem/hamster[hamster gem] (`Hamster::Vector`, `Hamster::Hash`, `Hamster::Set`) and https://github.com/ruby-concurrency/concurrent-ruby[concurrent-ruby gem] (`Concurrent::Array`, `Concurrent::Tuple`, `Concurrent::Hash`, `Concurrent::Map`) data structures:
|
|
261
|
+
And it works for https://github.com/hamstergem/hamster[hamster gem] (`Hamster::Vector`, `Hamster::Hash`, `Hamster::Set`), https://github.com/immutable-ruby/immutable-ruby[immutable-ruby gem] (`Immutable::Vector`, `Immutable::Hash`, `Immutable::Set`) and https://github.com/ruby-concurrency/concurrent-ruby[concurrent-ruby gem] (`Concurrent::Array`, `Concurrent::Tuple`, `Concurrent::Hash`, `Concurrent::Map`) data structures:
|
|
262
262
|
|
|
263
263
|
[source,ruby]
|
|
264
264
|
----
|
|
265
|
-
my_vector =
|
|
265
|
+
my_vector = Immutable::Vector[1, 2, 3]
|
|
266
266
|
💎ify[my_vector]
|
|
267
267
|
# => Persistent💎::Array[1, 2, 3]
|
|
268
268
|
|
|
@@ -275,7 +275,7 @@ my_tuple.set(0, :hello)
|
|
|
275
275
|
💎ify[my_tuple]
|
|
276
276
|
# => Persistent💎::Array[:hello]
|
|
277
277
|
|
|
278
|
-
my_hash =
|
|
278
|
+
my_hash = Immutable::Hash[hello: :world]
|
|
279
279
|
💎ify[my_hash]
|
|
280
280
|
# => Persistent💎::Hash[:hello => :world]
|
|
281
281
|
|
|
@@ -288,7 +288,7 @@ my_map[:hello] = :world
|
|
|
288
288
|
💎ify[my_map]
|
|
289
289
|
# => Persistent💎::Hash[:hello => :world]
|
|
290
290
|
|
|
291
|
-
my_set =
|
|
291
|
+
my_set = Immutable::Set[:hello, :world]
|
|
292
292
|
💎ify[my_set]
|
|
293
293
|
# => Persistent💎::Set[:hello, :world]
|
|
294
294
|
----
|
|
@@ -418,28 +418,28 @@ my_concurrent_map = my_hash.to_concurrent_map
|
|
|
418
418
|
|
|
419
419
|
=== API documentation for the persistent structures
|
|
420
420
|
|
|
421
|
-
Because the persistent structures are provided by the awesome https://github.com/
|
|
421
|
+
Because the persistent structures are provided by the awesome https://github.com/immutable-ruby/immutable-ruby[immutable-ruby gem], you can refer back to immutable-ruby's API docs for details on the operations provided by each data structure.
|
|
422
422
|
|
|
423
423
|
==== Array
|
|
424
424
|
|
|
425
|
-
Built on top of `
|
|
425
|
+
Built on top of `Immutable::Vector`
|
|
426
426
|
|
|
427
|
-
* https://github.com/
|
|
428
|
-
*
|
|
427
|
+
* https://github.com/immutable-ruby/immutable-ruby#vector-api-documentation[Example usage]
|
|
428
|
+
* https://rubydoc.info/github/immutable-ruby/immutable-ruby/master/Immutable/Vector[API docs]
|
|
429
429
|
|
|
430
430
|
==== Hash
|
|
431
431
|
|
|
432
|
-
Built on top of `
|
|
432
|
+
Built on top of `Immutable::Hash`
|
|
433
433
|
|
|
434
|
-
* https://github.com/
|
|
435
|
-
* http://rubydoc.info/github/
|
|
434
|
+
* https://github.com/immutable-ruby/immutable-ruby#hash-api-documentation[Example usage]
|
|
435
|
+
* http://rubydoc.info/github/immutable-ruby/immutable-ruby/master/Immutable/Hash[API docs]
|
|
436
436
|
|
|
437
437
|
==== Set
|
|
438
438
|
|
|
439
|
-
Built on top of `
|
|
439
|
+
Built on top of `Immutable::Set`
|
|
440
440
|
|
|
441
|
-
* https://github.com/
|
|
442
|
-
* http://
|
|
441
|
+
* https://github.com/immutable-ruby/immutable-ruby#set-api-documentation[Example usage]
|
|
442
|
+
* http://rubydoc.info/github/immutable-ruby/immutable-ruby/master/Immutable/Set[API docs]
|
|
443
443
|
|
|
444
444
|
== AAARGH YOU FIEND WHY IS THERE AN EMOJI ON MY CODEBASE?
|
|
445
445
|
|
|
@@ -504,6 +504,6 @@ Everyone interacting in the Persistent-💎 project’s codebases, issue tracker
|
|
|
504
504
|
|
|
505
505
|
Interested in immutable/persistent data structures? Here are some interesting resources for your exploration:
|
|
506
506
|
|
|
507
|
-
* https://github.com/hamstergem/hamster[hamster gem]
|
|
508
507
|
* https://github.com/immutable-ruby/immutable-ruby[immmutable-ruby gem]
|
|
508
|
+
* https://github.com/hamstergem/hamster[hamster gem]
|
|
509
509
|
* https://gitlab.com/ivoanjo/persistent-dmnd/issues[Your suggestion here]
|
data/Rakefile
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require "bundler/gem_tasks"
|
|
2
|
+
require "standard/rake" if RUBY_VERSION >= "2.6.0"
|
|
3
|
+
require "rspec/core/rake_task"
|
|
3
4
|
|
|
4
5
|
RSpec::Core::RakeTask.new(:spec)
|
|
5
6
|
|
|
6
|
-
task :
|
|
7
|
+
task default: [:"standard:fix", :spec]
|
data/UPSTREAM_TODO.adoc
CHANGED
|
@@ -120,13 +120,3 @@ def <=>(other)
|
|
|
120
120
|
self == other ? 0 : nil
|
|
121
121
|
end
|
|
122
122
|
----
|
|
123
|
-
|
|
124
|
-
=== Fix `Hash` comparison with Ruby hashes using `<`/`+++<=+++` breaks on Ruby 2.2 or older
|
|
125
|
-
|
|
126
|
-
Because the default implementation of this methods is `other > self` or `other >= self`, this breaks on older rubies as Hash does not implement these methods.
|
|
127
|
-
|
|
128
|
-
By relying supplying our own comparison code (similar to `>`/`>=`) we can workaround this.
|
|
129
|
-
|
|
130
|
-
=== Fix unneeded complex comparison in `Hash#>`
|
|
131
|
-
|
|
132
|
-
Instead of implementing it as `self != other && self >= other` and thus requiring twice the iterations/comparisons, this can just be `self.size > other.size`.
|
data/gems.rb
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
# typed: false
|
|
3
|
-
|
|
4
1
|
source "https://rubygems.org"
|
|
5
2
|
|
|
6
3
|
gemspec
|
|
@@ -8,4 +5,4 @@ gemspec
|
|
|
8
5
|
# Specify ffi version to avoid dependency issues when switching between MRI
|
|
9
6
|
# and JRuby with the same gems.lock
|
|
10
7
|
# Only used in development
|
|
11
|
-
gem "ffi", "~> 1.
|
|
8
|
+
gem "ffi", "~> 1.15.5"
|
data/lib/persistent-dmnd.rb
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
# typed: true
|
|
3
|
-
|
|
4
1
|
# Persistent-💎: Ruby gem for easily creating immutable data structures
|
|
5
2
|
# Copyright (c) 2017-2021 Ivo Anjo <ivo@ivoanjo.me>
|
|
6
3
|
#
|
|
@@ -35,11 +32,8 @@ require "persistent_dmnd/array"
|
|
|
35
32
|
require "persistent_dmnd/hash"
|
|
36
33
|
require "persistent_dmnd/set"
|
|
37
34
|
require "persistent_dmnd/dmndifier"
|
|
38
|
-
require "persistent_dmnd/jruby_workaround"
|
|
39
35
|
|
|
40
36
|
module Persistent💎
|
|
41
|
-
include JRubyWorkaround
|
|
42
|
-
|
|
43
37
|
def self.included(klass)
|
|
44
38
|
# Make methods on this module also available inside classes (e.g. not just in instances)
|
|
45
39
|
klass.extend(self)
|
|
@@ -103,7 +97,7 @@ module Persistent💎
|
|
|
103
97
|
# * Converts strings into immutable Strings (without modifying the original String)
|
|
104
98
|
# * Converts objects that answer to #to_str into frozen Strings
|
|
105
99
|
# * Converts sets (e.g. something that #is_a?(::Set) or answers to #to_set) into persistent sets
|
|
106
|
-
# * Converts Hamster and Concurrent (from concurrent-ruby) data structures to their persistent counterparts
|
|
100
|
+
# * Converts Hamster (from hamster), Immutable and Concurrent (from concurrent-ruby) data structures to their persistent counterparts
|
|
107
101
|
#
|
|
108
102
|
def 💎ify
|
|
109
103
|
Persistent💎::Dmndifier
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
# typed: false
|
|
3
|
-
|
|
4
1
|
# Persistent-💎: Ruby gem for easily creating immutable data structures
|
|
5
2
|
# Copyright (c) 2017-2021 Ivo Anjo <ivo@ivoanjo.me>
|
|
6
3
|
#
|
|
@@ -33,16 +30,14 @@
|
|
|
33
30
|
require "persistent_dmnd/self_conversion"
|
|
34
31
|
require "persistent_dmnd/is_persistent"
|
|
35
32
|
require "persistent_dmnd/concurrent_ruby_support"
|
|
36
|
-
require "persistent_dmnd/jruby_workaround"
|
|
37
33
|
|
|
38
|
-
require "
|
|
34
|
+
require "immutable"
|
|
39
35
|
require "set"
|
|
40
36
|
|
|
41
37
|
module Persistent💎
|
|
42
|
-
class Array <
|
|
38
|
+
class Array < Immutable::Vector
|
|
43
39
|
include SelfConversion
|
|
44
40
|
include IsPersistent
|
|
45
|
-
include JRubyWorkaround
|
|
46
41
|
include Persistent💎
|
|
47
42
|
|
|
48
43
|
def self.[](*items)
|
|
@@ -60,11 +55,11 @@ module Persistent💎
|
|
|
60
55
|
# my_concurrent_array = my_array.to_concurrent_array
|
|
61
56
|
#
|
|
62
57
|
def to_concurrent_array
|
|
63
|
-
ConcurrentRubySupport
|
|
58
|
+
ConcurrentRubySupport.ensure_concurrent_ruby_loaded
|
|
64
59
|
Concurrent::Array.new(self)
|
|
65
60
|
end
|
|
66
61
|
|
|
67
|
-
|
|
62
|
+
alias_method :to_concurrent, :to_concurrent_array
|
|
68
63
|
|
|
69
64
|
# Return Concurrent::Tuple with contents of Persistent💎::Array
|
|
70
65
|
#
|
|
@@ -74,7 +69,7 @@ module Persistent💎
|
|
|
74
69
|
# # => #<Concurrent::Tuple @size=2, @tuple=[<#Concurrent::AtomicReference value:hello>, <#Concurrent::AtomicReference value:world>]>
|
|
75
70
|
#
|
|
76
71
|
def to_concurrent_tuple
|
|
77
|
-
ConcurrentRubySupport
|
|
72
|
+
ConcurrentRubySupport.ensure_concurrent_ruby_loaded
|
|
78
73
|
each.with_index.each_with_object(Concurrent::Tuple.new(size)) do |(item, index), result|
|
|
79
74
|
result.set(index, item)
|
|
80
75
|
end
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
# typed: true
|
|
3
|
-
|
|
4
1
|
# Persistent-💎: Ruby gem for easily creating immutable data structures
|
|
5
2
|
# Copyright (c) 2017-2021 Ivo Anjo <ivo@ivoanjo.me>
|
|
6
3
|
#
|
|
@@ -30,8 +27,6 @@
|
|
|
30
27
|
|
|
31
28
|
# frozen_string_literal: true
|
|
32
29
|
|
|
33
|
-
require "thread"
|
|
34
|
-
|
|
35
30
|
module Persistent💎
|
|
36
31
|
# Simple module that attempts to load concurrent-ruby, and then stores the result for quick lookup
|
|
37
32
|
# This way we take care of loading concurrent-ruby ONLY when the library client asks us to, thus not bloating
|
|
@@ -66,7 +61,7 @@ module Persistent💎
|
|
|
66
61
|
|
|
67
62
|
def raise_no_concurrent_ruby
|
|
68
63
|
raise(NotImplementedError,
|
|
69
|
-
|
|
64
|
+
"concurrent-ruby gem is not available, please install it in order to use #to_concurrent and #to_concurrent_* methods")
|
|
70
65
|
end
|
|
71
66
|
|
|
72
67
|
# The following methods are only for internal and test usage. Please do not use them :)
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
# typed: true
|
|
3
|
-
|
|
4
1
|
# Persistent-💎: Ruby gem for easily creating immutable data structures
|
|
5
2
|
# Copyright (c) 2017-2021 Ivo Anjo <ivo@ivoanjo.me>
|
|
6
3
|
#
|
|
@@ -30,9 +27,7 @@
|
|
|
30
27
|
|
|
31
28
|
# frozen_string_literal: true
|
|
32
29
|
|
|
33
|
-
require "
|
|
34
|
-
|
|
35
|
-
require "hamster"
|
|
30
|
+
require "immutable"
|
|
36
31
|
|
|
37
32
|
module Persistent💎
|
|
38
33
|
class Dmndifier
|
|
@@ -41,32 +36,35 @@ module Persistent💎
|
|
|
41
36
|
DEFAULT_OPTIONS = {
|
|
42
37
|
on_unknown: proc { |arg|
|
|
43
38
|
raise ArgumentError, "Could not 💎ify an object of class #{arg.class}. Maybe you need to implement :to_💎?"
|
|
44
|
-
}
|
|
39
|
+
}
|
|
45
40
|
}.freeze
|
|
46
41
|
|
|
47
42
|
private_constant :DEFAULT_OPTIONS
|
|
48
43
|
|
|
49
44
|
def self.[](arg, options = DEFAULT_OPTIONS)
|
|
50
45
|
options = DEFAULT_OPTIONS.merge(options)
|
|
51
|
-
|
|
52
|
-
when arg.respond_to?(:to_💎)
|
|
46
|
+
if arg.respond_to?(:to_💎)
|
|
53
47
|
arg.to_💎
|
|
54
|
-
|
|
48
|
+
elsif arg.respond_to?(:to_dmnd)
|
|
55
49
|
arg.to_dmnd
|
|
56
|
-
|
|
50
|
+
elsif arg.respond_to?(:to_hash)
|
|
57
51
|
h💎[arg.to_hash]
|
|
58
|
-
|
|
52
|
+
elsif arg.is_a?(Immutable::Set) || arg.is_a?(Immutable::SortedSet)
|
|
53
|
+
s💎[*arg.to_a]
|
|
54
|
+
elsif defined?(Hamster::Set) && arg.is_a?(Hamster::Set)
|
|
55
|
+
s💎[*arg.to_a]
|
|
56
|
+
elsif defined?(Hamster::SortedSet) && arg.is_a?(Hamster::SortedSet)
|
|
59
57
|
s💎[*arg.to_a]
|
|
60
|
-
|
|
58
|
+
elsif arg.respond_to?(:to_ary)
|
|
61
59
|
a💎[*arg.to_ary]
|
|
62
|
-
|
|
60
|
+
elsif defined?(Concurrent::Tuple) && arg.is_a?(Concurrent::Tuple)
|
|
63
61
|
a💎[*arg.to_a]
|
|
64
|
-
|
|
62
|
+
elsif arg.respond_to?(:to_set)
|
|
65
63
|
s💎[*arg.to_set.to_a]
|
|
66
|
-
|
|
67
|
-
h💎[
|
|
68
|
-
|
|
69
|
-
h💎[
|
|
64
|
+
elsif defined?(Concurrent::Map) && arg.is_a?(Concurrent::Map)
|
|
65
|
+
h💎[arg.enum_for(:each_pair).to_h]
|
|
66
|
+
elsif arg.respond_to?(:each_pair)
|
|
67
|
+
h💎[arg.each_pair.to_h]
|
|
70
68
|
else
|
|
71
69
|
options.fetch(:on_unknown).call(arg)
|
|
72
70
|
end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
# typed: strict
|
|
3
1
|
# Persistent-💎: Ruby gem for easily creating immutable data structures
|
|
4
2
|
# Copyright (c) 2017-2021 Ivo Anjo <ivo@ivoanjo.me>
|
|
5
3
|
#
|
|
@@ -32,4 +30,4 @@
|
|
|
32
30
|
require "persistent-💎"
|
|
33
31
|
|
|
34
32
|
# Add our module to the main object, allowing our syntax to be used everywhere
|
|
35
|
-
include Persistent💎
|
|
33
|
+
include Persistent💎 # standard:disable Style/MixinUsage
|
data/lib/persistent_dmnd/hash.rb
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
# typed: false
|
|
3
|
-
|
|
4
1
|
# Persistent-💎: Ruby gem for easily creating immutable data structures
|
|
5
2
|
# Copyright (c) 2017-2021 Ivo Anjo <ivo@ivoanjo.me>
|
|
6
3
|
#
|
|
@@ -33,16 +30,14 @@
|
|
|
33
30
|
require "persistent_dmnd/self_conversion"
|
|
34
31
|
require "persistent_dmnd/is_persistent"
|
|
35
32
|
require "persistent_dmnd/concurrent_ruby_support"
|
|
36
|
-
require "persistent_dmnd/jruby_workaround"
|
|
37
33
|
|
|
38
|
-
require "
|
|
34
|
+
require "immutable"
|
|
39
35
|
require "set"
|
|
40
36
|
|
|
41
37
|
module Persistent💎
|
|
42
|
-
class Hash <
|
|
38
|
+
class Hash < Immutable::Hash
|
|
43
39
|
include SelfConversion
|
|
44
40
|
include IsPersistent
|
|
45
|
-
include JRubyWorkaround
|
|
46
41
|
include Persistent💎
|
|
47
42
|
|
|
48
43
|
# Hashes are not arrays and thus should not implement :to_ary
|
|
@@ -55,11 +50,11 @@ module Persistent💎
|
|
|
55
50
|
# my_concurrent_hash = my_hash.to_concurrent_hash
|
|
56
51
|
#
|
|
57
52
|
def to_concurrent_hash
|
|
58
|
-
ConcurrentRubySupport
|
|
53
|
+
ConcurrentRubySupport.ensure_concurrent_ruby_loaded
|
|
59
54
|
Concurrent::Hash[self]
|
|
60
55
|
end
|
|
61
56
|
|
|
62
|
-
|
|
57
|
+
alias_method :to_concurrent, :to_concurrent_hash
|
|
63
58
|
|
|
64
59
|
# Return Concurrent::Map with contents of Persistent💎::Hash
|
|
65
60
|
#
|
|
@@ -69,7 +64,7 @@ module Persistent💎
|
|
|
69
64
|
# # => #<Concurrent::Map:0x0055ad9b283ea0 entries=1 default_proc=nil>
|
|
70
65
|
#
|
|
71
66
|
def to_concurrent_map
|
|
72
|
-
ConcurrentRubySupport
|
|
67
|
+
ConcurrentRubySupport.ensure_concurrent_ruby_loaded
|
|
73
68
|
each_with_object(Concurrent::Map.new(initial_capacity: size)) do |(key, value), result|
|
|
74
69
|
result[key] = value
|
|
75
70
|
end
|
|
@@ -79,26 +74,6 @@ module Persistent💎
|
|
|
79
74
|
::Set.new(self)
|
|
80
75
|
end
|
|
81
76
|
|
|
82
|
-
def <(other)
|
|
83
|
-
if size >= other.size
|
|
84
|
-
false
|
|
85
|
-
else
|
|
86
|
-
self <= other
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def <=(other)
|
|
91
|
-
if size > other.size
|
|
92
|
-
false
|
|
93
|
-
else
|
|
94
|
-
each do |key, value|
|
|
95
|
-
return false if other[key] != value
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
true
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
77
|
# Return each entry as a key, value pair inside an immutable array
|
|
103
78
|
def each💎
|
|
104
79
|
if block_given?
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
# typed: false
|
|
3
|
-
|
|
4
1
|
# Persistent-💎: Ruby gem for easily creating immutable data structures
|
|
5
2
|
# Copyright (c) 2017-2021 Ivo Anjo <ivo@ivoanjo.me>
|
|
6
3
|
#
|
|
@@ -43,34 +40,34 @@ module Persistent💎
|
|
|
43
40
|
end
|
|
44
41
|
end
|
|
45
42
|
|
|
46
|
-
if RUBY_PLATFORM == "java" &&
|
|
43
|
+
if RUBY_PLATFORM == "java" && JRUBY_VERSION.start_with?("9.2.", "9.3.", "9.4.") && workaround_needed?
|
|
47
44
|
class ::Set
|
|
48
45
|
# Save existing Set methods
|
|
49
46
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
47
|
+
alias_method :persistent_dmnd_workaround_original_equal, :==
|
|
48
|
+
alias_method :persistent_dmnd_workaround_original_superset?, :superset?
|
|
49
|
+
alias_method :persistent_dmnd_workaround_original_proper_superset?, :proper_superset?
|
|
50
|
+
alias_method :persistent_dmnd_workaround_original_subset?, :subset?
|
|
51
|
+
alias_method :persistent_dmnd_workaround_original_proper_subset?, :proper_subset?
|
|
52
|
+
alias_method :persistent_dmnd_workaround_original_intersect?, :intersect?
|
|
53
|
+
alias_method :persistent_dmnd_workaround_original_disjoint?, :disjoint?
|
|
54
|
+
alias_method :persistent_dmnd_workaround_original_flatten_merge, :flatten_merge
|
|
55
|
+
alias_method :persistent_dmnd_workaround_original_flatten, :flatten
|
|
56
|
+
alias_method :persistent_dmnd_workaround_original_flatten!, :flatten!
|
|
57
|
+
alias_method :persistent_dmnd_workaround_original_spaceship, :<=>
|
|
61
58
|
|
|
62
59
|
# Redefine all set methods that use instanceof RubySet to restore previous behavior
|
|
63
60
|
|
|
64
61
|
if JRUBY_VERSION.start_with?("9.4.")
|
|
65
|
-
def <=>(
|
|
66
|
-
original =
|
|
62
|
+
def <=>(other)
|
|
63
|
+
original = persistent_dmnd_workaround_original_spaceship(other)
|
|
67
64
|
return original if original
|
|
68
65
|
|
|
69
|
-
return unless
|
|
70
|
-
case size <=>
|
|
71
|
-
when -1 then -1 if proper_subset?(
|
|
72
|
-
when +1 then +1 if proper_superset?(
|
|
73
|
-
else 0 if self.==(
|
|
66
|
+
return unless other.is_a?(::Set)
|
|
67
|
+
case size <=> other.size
|
|
68
|
+
when -1 then -1 if proper_subset?(other)
|
|
69
|
+
when +1 then +1 if proper_superset?(other)
|
|
70
|
+
else 0 if self.==(other)
|
|
74
71
|
end
|
|
75
72
|
end
|
|
76
73
|
end
|
|
@@ -123,11 +120,14 @@ module Persistent💎
|
|
|
123
120
|
persistent_dmnd_workaround_original_disjoint?(set)
|
|
124
121
|
rescue ArgumentError => e
|
|
125
122
|
raise unless e.message == "value must be a set" && set.is_a?(::Set)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
|
|
124
|
+
!(
|
|
125
|
+
if size < set.size
|
|
126
|
+
any? { |o| set.include?(o) }
|
|
127
|
+
else
|
|
128
|
+
set.any? { |o| include?(o) }
|
|
129
|
+
end
|
|
130
|
+
)
|
|
131
131
|
end
|
|
132
132
|
|
|
133
133
|
def flatten_merge(set, seen = ::Set.new)
|
|
@@ -153,15 +153,15 @@ module Persistent💎
|
|
|
153
153
|
end
|
|
154
154
|
|
|
155
155
|
def flatten!
|
|
156
|
-
replace(flatten
|
|
156
|
+
replace(flatten) if any? { |o| o.is_a?(::Set) }
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
# Reset aliases to point to redefined methods (otherwise they would keep on pointing to the old variants)
|
|
160
160
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
161
|
+
alias_method :>=, :superset?
|
|
162
|
+
alias_method :>, :proper_superset?
|
|
163
|
+
alias_method :<=, :subset?
|
|
164
|
+
alias_method :<, :proper_subset?
|
|
165
165
|
end
|
|
166
166
|
end
|
|
167
167
|
end
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
# typed: true
|
|
3
|
-
|
|
4
1
|
# Persistent-💎: Ruby gem for easily creating immutable data structures
|
|
5
2
|
# Copyright (c) 2017-2021 Ivo Anjo <ivo@ivoanjo.me>
|
|
6
3
|
#
|
|
@@ -30,13 +27,9 @@
|
|
|
30
27
|
|
|
31
28
|
# frozen_string_literal: true
|
|
32
29
|
|
|
33
|
-
require "persistent_dmnd/jruby_workaround"
|
|
34
|
-
|
|
35
30
|
module Persistent💎
|
|
36
31
|
# Implements trivial conversion to persistent data structures for our own classes
|
|
37
32
|
module SelfConversion
|
|
38
|
-
include JRubyWorkaround
|
|
39
|
-
|
|
40
33
|
def to_💎
|
|
41
34
|
self
|
|
42
35
|
end
|
data/lib/persistent_dmnd/set.rb
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
# typed: true
|
|
3
|
-
|
|
4
1
|
# Persistent-💎: Ruby gem for easily creating immutable data structures
|
|
5
2
|
# Copyright (c) 2017-2021 Ivo Anjo <ivo@ivoanjo.me>
|
|
6
3
|
#
|
|
@@ -33,17 +30,15 @@
|
|
|
33
30
|
require "persistent_dmnd/self_conversion"
|
|
34
31
|
require "persistent_dmnd/is_persistent"
|
|
35
32
|
require "persistent_dmnd/concurrent_ruby_support"
|
|
36
|
-
require "persistent_dmnd/jruby_workaround"
|
|
37
33
|
require "persistent_dmnd/jruby_9_2_set_workaround"
|
|
38
34
|
|
|
39
|
-
require "
|
|
35
|
+
require "immutable"
|
|
40
36
|
require "set"
|
|
41
37
|
|
|
42
38
|
module Persistent💎
|
|
43
|
-
class Set <
|
|
39
|
+
class Set < Immutable::Set
|
|
44
40
|
include SelfConversion
|
|
45
41
|
include IsPersistent
|
|
46
|
-
include JRubyWorkaround
|
|
47
42
|
include Persistent💎
|
|
48
43
|
|
|
49
44
|
def self.from_set(set)
|
|
@@ -69,10 +64,10 @@ module Persistent💎
|
|
|
69
64
|
# see also https://rubyreferences.github.io/rubychanges/3.0.html#standard-library for details
|
|
70
65
|
def <=>(other)
|
|
71
66
|
case size <=> other.size
|
|
72
|
-
when
|
|
73
|
-
|
|
74
|
-
when
|
|
75
|
-
|
|
67
|
+
when -1
|
|
68
|
+
-1 if self < other
|
|
69
|
+
when +1
|
|
70
|
+
+1 if self > other
|
|
76
71
|
else
|
|
77
72
|
0 if self == other
|
|
78
73
|
end
|
|
@@ -96,10 +91,12 @@ module Persistent💎
|
|
|
96
91
|
|
|
97
92
|
alias_method :to_sDmnd, :to_s💎
|
|
98
93
|
|
|
94
|
+
alias_method :===, :include?
|
|
95
|
+
|
|
99
96
|
private
|
|
100
97
|
|
|
101
98
|
def set_eq?(other)
|
|
102
|
-
|
|
99
|
+
size == other.size && other.all? { |item| include?(item) }
|
|
103
100
|
end
|
|
104
101
|
end
|
|
105
102
|
end
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
# typed: strong
|
|
3
|
-
|
|
4
1
|
# Persistent-💎: Ruby gem for easily creating immutable data structures
|
|
5
2
|
# Copyright (c) 2017-2021 Ivo Anjo <ivo@ivoanjo.me>
|
|
6
3
|
#
|
|
@@ -31,5 +28,5 @@
|
|
|
31
28
|
# frozen_string_literal: true
|
|
32
29
|
|
|
33
30
|
module Persistent💎
|
|
34
|
-
VERSION = "
|
|
31
|
+
VERSION = "3.0.0"
|
|
35
32
|
end
|
data/persistent-dmnd.gemspec
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
1
|
# Persistent-💎: Ruby gem for easily creating immutable data structures
|
|
4
2
|
# Copyright (c) 2017-2021 Ivo Anjo <ivo@ivoanjo.me>
|
|
5
3
|
#
|
|
@@ -49,20 +47,18 @@ Gem::Specification.new do |spec|
|
|
|
49
47
|
end
|
|
50
48
|
spec.require_paths = ["lib"]
|
|
51
49
|
|
|
52
|
-
spec.required_ruby_version = ">=
|
|
50
|
+
spec.required_ruby_version = ">= 2.4.0"
|
|
53
51
|
|
|
54
|
-
spec.add_development_dependency "bundler", "~> 1.
|
|
55
|
-
spec.add_development_dependency "rake", "~>
|
|
56
|
-
spec.add_development_dependency "rspec", "~> 3.
|
|
52
|
+
spec.add_development_dependency "bundler", "~> 1.17" if RUBY_VERSION < "2.6"
|
|
53
|
+
spec.add_development_dependency "rake", "~> 13.1"
|
|
54
|
+
spec.add_development_dependency "rspec", "~> 3.13"
|
|
57
55
|
spec.add_development_dependency "concurrent-ruby", "~> 1.1"
|
|
58
|
-
spec.add_development_dependency "
|
|
59
|
-
spec.add_development_dependency "pry"
|
|
60
|
-
spec.add_development_dependency "pry-byebug" if RUBY_ENGINE == "ruby"
|
|
61
|
-
spec.add_development_dependency "pry-debugger-jruby" if RUBY_ENGINE == "jruby"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
spec.add_development_dependency "spoom", "~> 1.1" if RUBY_VERSION >= "2.3.7"
|
|
65
|
-
end
|
|
56
|
+
spec.add_development_dependency "standard" if RUBY_VERSION >= "2.6.0"
|
|
57
|
+
spec.add_development_dependency "pry"
|
|
58
|
+
spec.add_development_dependency "pry-byebug" if RUBY_ENGINE == "ruby"
|
|
59
|
+
spec.add_development_dependency "pry-debugger-jruby" if RUBY_ENGINE == "jruby"
|
|
60
|
+
spec.add_development_dependency "hamster", ">= 3.0.0"
|
|
61
|
+
spec.add_development_dependency "warning", "~> 1.3.0"
|
|
66
62
|
|
|
67
|
-
spec.add_dependency "
|
|
63
|
+
spec.add_dependency "immutable-ruby", ">= 0.1.0"
|
|
68
64
|
end
|