set 0.1.0 → 1.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/.gitignore +1 -0
- data/CHANGELOG.md +19 -0
- data/Gemfile +1 -0
- data/LICENSE.txt +6 -4
- data/README.md +7 -28
- data/lib/set.rb +36 -252
- data/lib/set/sorted_set.rb +6 -0
- data/set.gemspec +3 -2
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9efb249e9dc58441358a2013c39ac9f9becd2de6728f107c1b5554935ffe0467
|
4
|
+
data.tar.gz: 8fe8e6f7a664ba006025b4b67ec80335093ef215e348481a44e12ee23b9e42d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76706c0faab6d07b44c213919862f779bf686eb70bd084cb7cbe0b7543de6aacd3c9146174ed4fa7954435c2739008267660c92fa8598890df64b0b9bb5d72e2
|
7
|
+
data.tar.gz: a86535d57dba0161abbbc04607ed41f6964fb101d0b236977508b0e7962796ac326911cae978f5035c9669bf2ec9564a5d4d52cad817fbd65276892485eecbda
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Set Changelog
|
2
|
+
|
3
|
+
## 1.0.0 (2020-12-21)
|
4
|
+
|
5
|
+
This is the first release of set as a gem. Here lists the changes since the version bundled with Ruby 2.7.
|
6
|
+
|
7
|
+
* Breaking Changes
|
8
|
+
* SortedSet has been removed for dependency and performance reasons. [#2][] ([@knu][])
|
9
|
+
|
10
|
+
* Enhancements
|
11
|
+
* Set#join is added as a shorthand for `.to_a.join`. [#4][] ([@marcandre][])
|
12
|
+
* Set#<=> is added. [#5][] ([@marcandre][])
|
13
|
+
|
14
|
+
[#2]: https://github.com/ruby/set/pull/2
|
15
|
+
[#4]: https://github.com/ruby/set/pull/4
|
16
|
+
[#5]: https://github.com/ruby/set/pull/5
|
17
|
+
|
18
|
+
[@knu]: https://github.com/knu
|
19
|
+
[@marcandre]: https://github.com/marcandre
|
data/Gemfile
CHANGED
data/LICENSE.txt
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
Copyright (
|
1
|
+
Copyright (c) 2002-2020 Akinori MUSHA
|
2
|
+
|
3
|
+
All rights reserved.
|
2
4
|
|
3
5
|
Redistribution and use in source and binary forms, with or without
|
4
6
|
modification, are permitted provided that the following conditions
|
5
7
|
are met:
|
6
8
|
1. Redistributions of source code must retain the above copyright
|
7
|
-
notice, this list of conditions and the following disclaimer.
|
9
|
+
notice, this list of conditions and the following disclaimer.
|
8
10
|
2. Redistributions in binary form must reproduce the above copyright
|
9
|
-
notice, this list of conditions and the following disclaimer in the
|
10
|
-
documentation and/or other materials provided with the distribution.
|
11
|
+
notice, this list of conditions and the following disclaimer in the
|
12
|
+
documentation and/or other materials provided with the distribution.
|
11
13
|
|
12
14
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
13
15
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
data/README.md
CHANGED
@@ -1,25 +1,8 @@
|
|
1
1
|
# Set
|
2
2
|
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/set`. To experiment with that code, run `bin/console` for an interactive prompt.
|
3
4
|
|
4
|
-
|
5
|
-
This is a hybrid of Array's intuitive inter-operation facilities and
|
6
|
-
Hash's fast lookup.
|
7
|
-
|
8
|
-
Set is easy to use with Enumerable objects (implementing +each+).
|
9
|
-
Most of the initializer methods and binary operators accept generic
|
10
|
-
Enumerable objects besides sets and arrays. An Enumerable object
|
11
|
-
can be converted to Set using the +to_set+ method.
|
12
|
-
|
13
|
-
Set uses Hash as storage, so you must note the following points:
|
14
|
-
|
15
|
-
* Equality of elements is determined according to Object#eql? and
|
16
|
-
Object#hash. Use Set#compare_by_identity to make a set compare
|
17
|
-
its elements by their identity.
|
18
|
-
* Set assumes that the identity of each element does not change
|
19
|
-
while it is stored. Modifying an element of a set will render the
|
20
|
-
set to an unreliable state.
|
21
|
-
* When a string is to be stored, a frozen copy of the string is
|
22
|
-
stored instead unless the original string is already frozen.
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
23
6
|
|
24
7
|
## Installation
|
25
8
|
|
@@ -39,15 +22,6 @@ Or install it yourself as:
|
|
39
22
|
|
40
23
|
## Usage
|
41
24
|
|
42
|
-
### Comparison
|
43
|
-
|
44
|
-
The comparison operators <, >, <=, and >= are implemented as
|
45
|
-
shorthand for the {proper_,}{subset?,superset?} methods. However,
|
46
|
-
the <=> operator is intentionally left out because not every pair of
|
47
|
-
sets is comparable ({x, y} vs. {x, z} for example).
|
48
|
-
|
49
|
-
### Example
|
50
|
-
|
51
25
|
```ruby
|
52
26
|
require 'set'
|
53
27
|
s1 = Set[1, 2] #=> #<Set: {1, 2}>
|
@@ -69,3 +43,8 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
69
43
|
|
70
44
|
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/set.
|
71
45
|
|
46
|
+
Feature requests should also go to https://bugs.ruby-lang.org/ for wider audience and discussion.
|
47
|
+
|
48
|
+
## License
|
49
|
+
|
50
|
+
The gem is available as open source under either the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). When bundled with Ruby, you can distribute/modify this program under the same terms of [Ruby](https://www.ruby-lang.org/en/about/license.txt).
|
data/lib/set.rb
CHANGED
@@ -16,12 +16,9 @@
|
|
16
16
|
#
|
17
17
|
# This library provides the Set class, which deals with a collection
|
18
18
|
# of unordered values with no duplicates. It is a hybrid of Array's
|
19
|
-
# intuitive inter-operation facilities and Hash's fast lookup.
|
20
|
-
# need to keep values sorted in some order, use the SortedSet class.
|
19
|
+
# intuitive inter-operation facilities and Hash's fast lookup.
|
21
20
|
#
|
22
21
|
# The method +to_set+ is added to Enumerable for convenience.
|
23
|
-
#
|
24
|
-
# See the Set and SortedSet documentation for examples of usage.
|
25
22
|
|
26
23
|
|
27
24
|
#
|
@@ -48,9 +45,9 @@
|
|
48
45
|
# == Comparison
|
49
46
|
#
|
50
47
|
# The comparison operators <, >, <=, and >= are implemented as
|
51
|
-
# shorthand for the {proper_,}{subset?,superset?} methods.
|
52
|
-
#
|
53
|
-
# sets
|
48
|
+
# shorthand for the {proper_,}{subset?,superset?} methods.
|
49
|
+
# The <=> operator reflects this order, or return `nil` for
|
50
|
+
# sets that both have distinct elements ({x, y} vs. {x, z} for example).
|
54
51
|
#
|
55
52
|
# == Example
|
56
53
|
#
|
@@ -136,10 +133,18 @@ class Set
|
|
136
133
|
@hash = orig.instance_variable_get(:@hash).dup
|
137
134
|
end
|
138
135
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
136
|
+
if Kernel.instance_method(:initialize_clone).arity != 1
|
137
|
+
# Clone internal hash.
|
138
|
+
def initialize_clone(orig, **options)
|
139
|
+
super
|
140
|
+
@hash = orig.instance_variable_get(:@hash).clone(**options)
|
141
|
+
end
|
142
|
+
else
|
143
|
+
# Clone internal hash.
|
144
|
+
def initialize_clone(orig)
|
145
|
+
super
|
146
|
+
@hash = orig.instance_variable_get(:@hash).clone
|
147
|
+
end
|
143
148
|
end
|
144
149
|
|
145
150
|
def freeze # :nodoc:
|
@@ -297,6 +302,19 @@ class Set
|
|
297
302
|
end
|
298
303
|
alias < proper_subset?
|
299
304
|
|
305
|
+
# Returns 0 if the set are equal,
|
306
|
+
# -1 / +1 if the set is a proper subset / superset of the given set,
|
307
|
+
# or nil if they both have unique elements.
|
308
|
+
def <=>(set)
|
309
|
+
return unless set.is_a?(Set)
|
310
|
+
|
311
|
+
case size <=> set.size
|
312
|
+
when -1 then -1 if proper_subset?(set)
|
313
|
+
when +1 then +1 if proper_superset?(set)
|
314
|
+
else 0 if self.==(set)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
300
318
|
# Returns true if the set and the given set have at least one
|
301
319
|
# element in common.
|
302
320
|
#
|
@@ -623,6 +641,12 @@ class Set
|
|
623
641
|
end
|
624
642
|
end
|
625
643
|
|
644
|
+
# Returns a string created by converting each element of the set to a string
|
645
|
+
# See also: Array#join
|
646
|
+
def join(separator=nil)
|
647
|
+
to_a.join(separator)
|
648
|
+
end
|
649
|
+
|
626
650
|
InspectKey = :__inspect_key__ # :nodoc:
|
627
651
|
|
628
652
|
# Returns a string containing a human-readable representation of the
|
@@ -659,154 +683,6 @@ class Set
|
|
659
683
|
end
|
660
684
|
end
|
661
685
|
|
662
|
-
#
|
663
|
-
# SortedSet implements a Set that guarantees that its elements are
|
664
|
-
# yielded in sorted order (according to the return values of their
|
665
|
-
# #<=> methods) when iterating over them.
|
666
|
-
#
|
667
|
-
# All elements that are added to a SortedSet must respond to the <=>
|
668
|
-
# method for comparison.
|
669
|
-
#
|
670
|
-
# Also, all elements must be <em>mutually comparable</em>: <tt>el1 <=>
|
671
|
-
# el2</tt> must not return <tt>nil</tt> for any elements <tt>el1</tt>
|
672
|
-
# and <tt>el2</tt>, else an ArgumentError will be raised when
|
673
|
-
# iterating over the SortedSet.
|
674
|
-
#
|
675
|
-
# == Example
|
676
|
-
#
|
677
|
-
# require "set"
|
678
|
-
#
|
679
|
-
# set = SortedSet.new([2, 1, 5, 6, 4, 5, 3, 3, 3])
|
680
|
-
# ary = []
|
681
|
-
#
|
682
|
-
# set.each do |obj|
|
683
|
-
# ary << obj
|
684
|
-
# end
|
685
|
-
#
|
686
|
-
# p ary # => [1, 2, 3, 4, 5, 6]
|
687
|
-
#
|
688
|
-
# set2 = SortedSet.new([1, 2, "3"])
|
689
|
-
# set2.each { |obj| } # => raises ArgumentError: comparison of Fixnum with String failed
|
690
|
-
#
|
691
|
-
class SortedSet < Set
|
692
|
-
@@setup = false
|
693
|
-
@@mutex = Mutex.new
|
694
|
-
|
695
|
-
class << self
|
696
|
-
def [](*ary) # :nodoc:
|
697
|
-
new(ary)
|
698
|
-
end
|
699
|
-
|
700
|
-
def setup # :nodoc:
|
701
|
-
@@setup and return
|
702
|
-
|
703
|
-
@@mutex.synchronize do
|
704
|
-
# a hack to shut up warning
|
705
|
-
alias_method :old_init, :initialize
|
706
|
-
|
707
|
-
begin
|
708
|
-
require 'rbtree'
|
709
|
-
|
710
|
-
module_eval <<-END, __FILE__, __LINE__+1
|
711
|
-
def initialize(*args)
|
712
|
-
@hash = RBTree.new
|
713
|
-
super
|
714
|
-
end
|
715
|
-
|
716
|
-
def add(o)
|
717
|
-
o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
|
718
|
-
super
|
719
|
-
end
|
720
|
-
alias << add
|
721
|
-
END
|
722
|
-
rescue LoadError
|
723
|
-
module_eval <<-END, __FILE__, __LINE__+1
|
724
|
-
def initialize(*args)
|
725
|
-
@keys = nil
|
726
|
-
super
|
727
|
-
end
|
728
|
-
|
729
|
-
def clear
|
730
|
-
@keys = nil
|
731
|
-
super
|
732
|
-
end
|
733
|
-
|
734
|
-
def replace(enum)
|
735
|
-
@keys = nil
|
736
|
-
super
|
737
|
-
end
|
738
|
-
|
739
|
-
def add(o)
|
740
|
-
o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
|
741
|
-
@keys = nil
|
742
|
-
super
|
743
|
-
end
|
744
|
-
alias << add
|
745
|
-
|
746
|
-
def delete(o)
|
747
|
-
@keys = nil
|
748
|
-
@hash.delete(o)
|
749
|
-
self
|
750
|
-
end
|
751
|
-
|
752
|
-
def delete_if
|
753
|
-
block_given? or return enum_for(__method__) { size }
|
754
|
-
n = @hash.size
|
755
|
-
super
|
756
|
-
@keys = nil if @hash.size != n
|
757
|
-
self
|
758
|
-
end
|
759
|
-
|
760
|
-
def keep_if
|
761
|
-
block_given? or return enum_for(__method__) { size }
|
762
|
-
n = @hash.size
|
763
|
-
super
|
764
|
-
@keys = nil if @hash.size != n
|
765
|
-
self
|
766
|
-
end
|
767
|
-
|
768
|
-
def merge(enum)
|
769
|
-
@keys = nil
|
770
|
-
super
|
771
|
-
end
|
772
|
-
|
773
|
-
def each(&block)
|
774
|
-
block or return enum_for(__method__) { size }
|
775
|
-
to_a.each(&block)
|
776
|
-
self
|
777
|
-
end
|
778
|
-
|
779
|
-
def to_a
|
780
|
-
(@keys = @hash.keys).sort! unless @keys
|
781
|
-
@keys.dup
|
782
|
-
end
|
783
|
-
|
784
|
-
def freeze
|
785
|
-
to_a
|
786
|
-
super
|
787
|
-
end
|
788
|
-
|
789
|
-
def rehash
|
790
|
-
@keys = nil
|
791
|
-
super
|
792
|
-
end
|
793
|
-
END
|
794
|
-
end
|
795
|
-
# a hack to shut up warning
|
796
|
-
remove_method :old_init
|
797
|
-
|
798
|
-
@@setup = true
|
799
|
-
end
|
800
|
-
end
|
801
|
-
end
|
802
|
-
|
803
|
-
def initialize(*args, &block) # :nodoc:
|
804
|
-
SortedSet.setup
|
805
|
-
@keys = nil
|
806
|
-
super
|
807
|
-
end
|
808
|
-
end
|
809
|
-
|
810
686
|
module Enumerable
|
811
687
|
# Makes a set from the enumerable object with given arguments.
|
812
688
|
# Needs to +require "set"+ to use this method.
|
@@ -815,96 +691,4 @@ module Enumerable
|
|
815
691
|
end
|
816
692
|
end
|
817
693
|
|
818
|
-
#
|
819
|
-
# == RestricedSet class
|
820
|
-
# RestricedSet implements a set with restrictions defined by a given
|
821
|
-
# block.
|
822
|
-
#
|
823
|
-
# === Super class
|
824
|
-
# Set
|
825
|
-
#
|
826
|
-
# === Class Methods
|
827
|
-
# --- RestricedSet::new(enum = nil) { |o| ... }
|
828
|
-
# --- RestricedSet::new(enum = nil) { |rset, o| ... }
|
829
|
-
# Creates a new restricted set containing the elements of the given
|
830
|
-
# enumerable object. Restrictions are defined by the given block.
|
831
|
-
#
|
832
|
-
# If the block's arity is 2, it is called with the RestrictedSet
|
833
|
-
# itself and an object to see if the object is allowed to be put in
|
834
|
-
# the set.
|
835
|
-
#
|
836
|
-
# Otherwise, the block is called with an object to see if the object
|
837
|
-
# is allowed to be put in the set.
|
838
|
-
#
|
839
|
-
# === Instance Methods
|
840
|
-
# --- restriction_proc
|
841
|
-
# Returns the restriction procedure of the set.
|
842
|
-
#
|
843
|
-
# =end
|
844
|
-
#
|
845
|
-
# class RestricedSet < Set
|
846
|
-
# def initialize(*args, &block)
|
847
|
-
# @proc = block or raise ArgumentError, "missing a block"
|
848
|
-
#
|
849
|
-
# if @proc.arity == 2
|
850
|
-
# instance_eval %{
|
851
|
-
# def add(o)
|
852
|
-
# @hash[o] = true if @proc.call(self, o)
|
853
|
-
# self
|
854
|
-
# end
|
855
|
-
# alias << add
|
856
|
-
#
|
857
|
-
# def add?(o)
|
858
|
-
# if include?(o) || !@proc.call(self, o)
|
859
|
-
# nil
|
860
|
-
# else
|
861
|
-
# @hash[o] = true
|
862
|
-
# self
|
863
|
-
# end
|
864
|
-
# end
|
865
|
-
#
|
866
|
-
# def replace(enum)
|
867
|
-
# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
|
868
|
-
# clear
|
869
|
-
# enum.each_entry { |o| add(o) }
|
870
|
-
#
|
871
|
-
# self
|
872
|
-
# end
|
873
|
-
#
|
874
|
-
# def merge(enum)
|
875
|
-
# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
|
876
|
-
# enum.each_entry { |o| add(o) }
|
877
|
-
#
|
878
|
-
# self
|
879
|
-
# end
|
880
|
-
# }
|
881
|
-
# else
|
882
|
-
# instance_eval %{
|
883
|
-
# def add(o)
|
884
|
-
# if @proc.call(o)
|
885
|
-
# @hash[o] = true
|
886
|
-
# end
|
887
|
-
# self
|
888
|
-
# end
|
889
|
-
# alias << add
|
890
|
-
#
|
891
|
-
# def add?(o)
|
892
|
-
# if include?(o) || !@proc.call(o)
|
893
|
-
# nil
|
894
|
-
# else
|
895
|
-
# @hash[o] = true
|
896
|
-
# self
|
897
|
-
# end
|
898
|
-
# end
|
899
|
-
# }
|
900
|
-
# end
|
901
|
-
#
|
902
|
-
# super(*args)
|
903
|
-
# end
|
904
|
-
#
|
905
|
-
# def restriction_proc
|
906
|
-
# @proc
|
907
|
-
# end
|
908
|
-
# end
|
909
|
-
|
910
|
-
# Tests have been moved to test/test_set.rb.
|
694
|
+
autoload :SortedSet, "#{__dir__}/set/sorted_set"
|
data/set.gemspec
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "set"
|
3
|
-
spec.version = "
|
3
|
+
spec.version = "1.0.0"
|
4
4
|
spec.authors = ["Akinori MUSHA"]
|
5
5
|
spec.email = ["knu@idaemons.org"]
|
6
6
|
|
7
7
|
spec.summary = %q{Provides a class to deal with collections of unordered, unique values}
|
8
8
|
spec.description = %q{Provides a class to deal with collections of unordered, unique values}
|
9
9
|
spec.homepage = "https://github.com/ruby/set"
|
10
|
+
spec.license = "BSD-2-Clause"
|
10
11
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
11
|
-
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
12
12
|
|
13
13
|
spec.metadata["homepage_uri"] = spec.homepage
|
14
14
|
spec.metadata["source_code_uri"] = spec.homepage
|
15
|
+
spec.metadata["changelog_uri"] = "https://github.com/ruby/set/blob/v#{spec.version}/CHANGELOG.md"
|
15
16
|
|
16
17
|
# Specify which files should be added to the gem when it is released.
|
17
18
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: set
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Akinori MUSHA
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-21 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Provides a class to deal with collections of unordered, unique values
|
14
14
|
email:
|
@@ -19,6 +19,7 @@ extra_rdoc_files: []
|
|
19
19
|
files:
|
20
20
|
- ".github/workflows/test.yml"
|
21
21
|
- ".gitignore"
|
22
|
+
- CHANGELOG.md
|
22
23
|
- Gemfile
|
23
24
|
- LICENSE.txt
|
24
25
|
- README.md
|
@@ -26,14 +27,15 @@ files:
|
|
26
27
|
- bin/console
|
27
28
|
- bin/setup
|
28
29
|
- lib/set.rb
|
30
|
+
- lib/set/sorted_set.rb
|
29
31
|
- set.gemspec
|
30
32
|
homepage: https://github.com/ruby/set
|
31
33
|
licenses:
|
32
|
-
- Ruby
|
33
34
|
- BSD-2-Clause
|
34
35
|
metadata:
|
35
36
|
homepage_uri: https://github.com/ruby/set
|
36
37
|
source_code_uri: https://github.com/ruby/set
|
38
|
+
changelog_uri: https://github.com/ruby/set/blob/v1.0.0/CHANGELOG.md
|
37
39
|
post_install_message:
|
38
40
|
rdoc_options: []
|
39
41
|
require_paths:
|
@@ -49,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
51
|
- !ruby/object:Gem::Version
|
50
52
|
version: '0'
|
51
53
|
requirements: []
|
52
|
-
rubygems_version: 3.2.
|
54
|
+
rubygems_version: 3.2.1
|
53
55
|
signing_key:
|
54
56
|
specification_version: 4
|
55
57
|
summary: Provides a class to deal with collections of unordered, unique values
|