rangeary 0.3.0 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a68fed02c28c7598ccd0e5e850012be4d1212948
4
- data.tar.gz: a13032cc6cd7020224255079aaf63f6f8d314411
2
+ SHA256:
3
+ metadata.gz: 0776d13fb0ae08187d7ff2dfaa89e8bd2a2e360fdebe7e62f94dfbd82f210d06
4
+ data.tar.gz: b39226c861c431fd132f2a215572ad5ea1a8bd843bcf2045be5ab8940667bd0c
5
5
  SHA512:
6
- metadata.gz: 6124f036424de4b48bbfa1950602677b61ba780c6d686cc95605803ac7d3e49547f36473f58bc1f148f629cdd5bb99e7e526ace4de95a1f2d8d39c9bfc8997ba
7
- data.tar.gz: 9bd1973fb2f6006363c7c5f8280a4462fc9f79239aa58183f50f0a899f63816a16b8c5dbf7f8b0e684ee6f7eb2aef191354d7d7abaf057f53ad8f8707d1ca938
6
+ metadata.gz: 2a1987ea2dd74dda7656ef8722af870bc713194dc51ee67dfdaa167b0d463ba0e18cdfb4d01f9841bb242ea0605c5916e3c6195aacec6b65e46543999169d727
7
+ data.tar.gz: 921b2ae2084d3f0f2230fd919f711ec47cf94b22438fa88ca0ae738f2d7193fb28b2794e0ef7ce484e54a74aa4bfd75fc22f8cf43b593a786b0e4193ba33fcc0
data/.gitignore ADDED
@@ -0,0 +1,55 @@
1
+ # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile '~/.gitignore_global'
6
+
7
+ # Ignore bundler config.
8
+ /.bundle
9
+ /vendor/bundle
10
+
11
+ # Ignore all logfiles and tempfiles.
12
+ /log/*
13
+ /tmp/*
14
+ !/log/.keep
15
+ !/tmp/.keep
16
+
17
+ .rbenv-version
18
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
19
+ .rvmrc
20
+
21
+ /node_modules
22
+ /yarn-error.log
23
+
24
+ .byebug_history
25
+
26
+ *.[oa]
27
+ *.so
28
+ *~
29
+ *.nogem
30
+ *nogem.*
31
+ *.bak
32
+ *.BAK
33
+ *.backup
34
+ *.org
35
+ *.orig
36
+ *.elc
37
+ *.pyc
38
+ \#*\#
39
+ .\#*
40
+
41
+ # Elastic Beanstalk Files
42
+ .elasticbeanstalk/*
43
+ !.elasticbeanstalk/*.cfg.yml
44
+ !.elasticbeanstalk/*.global.yml
45
+
46
+ # macOS
47
+ .DS_Store
48
+
49
+ # yard
50
+ *.yardoc
51
+
52
+ # Ruby Gem doc
53
+ *.gem
54
+ doc/*
55
+
data/ChangeLog CHANGED
@@ -1,3 +1,13 @@
1
+ -----
2
+ (Version: 1.0)
3
+ 2019-11-01 Masa Sakano
4
+ * Release of Ver.1! Fully compatible of Endless Range introduced in Ruby 2.6.
5
+ * requiring RangeExtd Ver.1.1 or later.
6
+ * Now requiring Ruby-2.1.
7
+ * The method infinities is now written explicitly, as opposed to attr_reader.
8
+ * Class method comparable_end is added.
9
+ * Major refactoring in the initialisation routine and Array#== .
10
+
1
11
  -----
2
12
  (Version: 0.3.0)
3
13
  2016-05-27 Masa Sakano
data/Makefile ADDED
@@ -0,0 +1,23 @@
1
+ ALL =
2
+
3
+ objs =
4
+
5
+ .SUFFIXES: .so .o .c .f
6
+
7
+ #.o.so:
8
+ # ${LD} ${LFLAGS} -o $@ $< ${LINK_LIB}
9
+
10
+ all: ${ALL}
11
+
12
+
13
+ .PHONY: clean test doc
14
+ clean:
15
+ $(RM) bin/*~
16
+
17
+ ## You may need RUBYLIB=`pwd`/lib:$RUBYLIB
18
+ test:
19
+ rake test
20
+
21
+ doc:
22
+ yard doc; [[ -x ".github" && ( "README.ja.rdoc" -nt ".github/README.md" ) ]] && ( ruby -r rdoc -e 'puts RDoc::Markup::ToMarkdown.new.convert ARGF.read' < README.ja.rdoc > .github/README.md ; echo ".github/README.md is updated." ) || exit 0
23
+
data/News CHANGED
@@ -1,3 +1,7 @@
1
+ -----
2
+ (Version: 1.0) 2019-11-01
3
+ * Release of Version 1.0. Endless Range in Ruby 2.6 is supported for range_extd '>= 1.1'
4
+
1
5
  -----
2
6
  (Version: 0.2.0) 2014-05-11
3
7
  * New method of Rangeary#equiv?(), following the upgraded dependency on range_extd '>= 0.4.0'.
data/README.ja.rdoc CHANGED
@@ -2,13 +2,15 @@
2
2
  = Rangeary - Multiple Range(Extd) class
3
3
 
4
4
  This package defines Rangeary class, which contains any multiple
5
- 1-dimensional ranges ({RangeExtd} objects). For example, a multiple
5
+ 1-dimensional ranges ({RangeExtd}[http://rubygems.org/gems/range_extd] objects). For example, a multiple
6
6
  range of
7
+
7
8
  0.5 < x <= 2.5, 6.0 <= x < 8.0, 10.0 <= x (<= Infinity)
9
+
8
10
  for <tt>x</tt> can be defined in this class.
9
11
 
10
12
  The element objects for {Rangeary} can be anthing that can form
11
- {RangeExtd} objects; not only Numeric (or Real) but anything
13
+ RangeExtd objects; not only Numeric (or Real) but anything
12
14
  Comparable. {Rangeary} accepts the built-in Range-class objects for
13
15
  the elements in initialisation, too.
14
16
 
@@ -21,7 +23,7 @@ All the four standard logical operations, that is, negation
21
23
  alter the contents.
22
24
 
23
25
  Practically, {Rangeary} is a sub-class of Array, works as an array of
24
- {RangeExtd}, and inherits most of the methods, hence you can apply most
26
+ RangeExtd, and inherits most of the methods, hence you can apply most
25
27
  operations to {Rangeary} that Array accpets, within the restriction of
26
28
  immutability of {Rangeary}. In addition, {Rangeary} offers several
27
29
  methods that directly work on its element as a range. In the above
@@ -33,35 +35,47 @@ With this class, logical operations of 1-dimensional range objects are
33
35
  now possible and easy.
34
36
  I hope you find it to be useful.
35
37
 
38
+ === News: Endless Range supported
39
+
40
+ Now, as of 2019 October, this fully supports {Endless Range}[https://rubyreferences.github.io/rubychanges/2.6.html#endless-range-1]
41
+ introduced in Ruby 2.6. It is released as Version 1.* finally!
42
+
36
43
 
37
44
  == Install
38
45
 
39
- First, you need {RangeExtd} class library (basically, two files of pure ruby code), which is in gem:
46
+ First, you need {RangeExtd}[https://rubygems.org/gems/range_extd] class library (basically, two files of pure ruby code), which is in gem:
47
+
40
48
  gem install range_extd
49
+
41
50
  Or, get it from
42
- {https://rubygems.org/gems/range_extd}
51
+ https://rubygems.org/gems/range_extd
43
52
  if you have not yet installed it.
44
53
 
45
54
  Then, install this library.
55
+
46
56
  gem install rangeary
47
57
 
48
58
  A file
59
+
49
60
  rangeary/rangeary.rb
61
+
50
62
  should be installed in one of your <tt>$LOAD_PATH</tt>.
51
63
  Alternatively, get it from
52
- {http://rubygems.org/gems/rangeary}
64
+ http://rubygems.org/gems/rangeary
53
65
 
54
66
  Then all you need to do is
67
+
55
68
  require 'rangeary/rangeary'
69
+
56
70
  or, possibly as follows, if you manually install it
71
+
57
72
  require 'rangeary'
73
+
58
74
  in your Ruby script (or irb). The library files like
59
- <tt>range_extd/range_extd.rb</tt> for {RangeExtd} is automatically
75
+ <tt>range_extd/range_extd.rb</tt> for RangeExtd are automatically
60
76
  loaded.
61
77
 
62
- {Rangeary} itself may work in Ruby 1.8, but {RangeExtd} works in only
63
- Ruby 2.0 (or maybe 1.9.3) and above, hence {Rangeary} does not work in
64
- Ruby 1.8 or earlier.
78
+ {Rangeary} itself may work in Ruby 1.8, but RangeExtd works in only Ruby 2.1 or later.
65
79
 
66
80
  Have fun!
67
81
 
@@ -79,9 +93,9 @@ Here are some simple examples.
79
93
  Rangeary(true..true) # => ArgumentError
80
94
 
81
95
  Basically, <tt>Rangeary()</tt> or <tt>Rangeary.new()</tt> accepts
82
- an arbitrary number of either {Range}, {RangeExtd}, {Rangeary}, or a
96
+ an arbitrary number of either Range, RangeExtd, {Rangeary}, or a
83
97
  combination of them. Note Range objects that return false in
84
- {Range#valid?} will raise an exception.
98
+ +Range#valid?+ will raise an exception.
85
99
 
86
100
  For more detail and examples, see {Rangeary.new}.
87
101
 
@@ -103,22 +117,25 @@ For more detail and examples, see {Rangeary.new}.
103
117
  rb + Rangeary(3..7) # => [2...9]
104
118
  rb - Rangeary(3..7) # => [2...3, RangeExtd(7,'<...',9)]
105
119
  rb * Rangeary(4..5, 8..10) # => [4..4, 8...9]
106
- rb.negation # => [-Float::INFINITY...2, RangeExtd(4,'<...',6), 9..Float::INFINITY]
120
+ ~rb # => [-Float::INFINITY...2, RangeExtd(4,'<...',6), 9..Float::INFINITY]
121
+
122
+ rc = Rangeary(?d...?x, negative: ?a, positive: ?z)
123
+ ~rc # => [?a...?d, ?x..?z]
124
+
125
+ where +~rb+ is equivalent to +rb.negation+. In the last example, it
126
+ provides the user-defined *infinities*.
107
127
 
108
128
  Most of the methods that are in the built-in Array can be used, as long as
109
129
  it does not violate the immutability of {Rangeary} objects, such as
110
- {Array#push}.
130
+ +Array#push+.
111
131
 
112
132
 
113
133
  == Description
114
134
 
115
- Once the file <tt>rangeary.rb</tt> is required, a class is defined, in
135
+ Once the file <tt>rangeary.rb</tt> is required, the class +Rangeary+ is defined, in
116
136
  addtion to the two defined in the RangeExtd library
117
137
  (<tt>RangeExtd</tt> and <tt>RangeExtd::Infinity</tt>).
118
138
 
119
- * Rangeary
120
-
121
-
122
139
  === Rangeary Class
123
140
 
124
141
  {Rangeary} objects are immutable, the same as Range and RangeExtd.
@@ -126,73 +143,185 @@ Hence once an instance is created, it would not change.
126
143
 
127
144
  How to create an instance is explained above (in the Examples
128
145
  sections). Any attempt to try to create an instance with one of
129
- elements being not "valid" as a range, that is, {Range#valid?} returns
146
+ elements being not "valid" as a range, that is, +Range#valid?+ returns
130
147
  false, raises an exception (<tt>ArgumentError</tt>), and fails.
131
148
 
132
- Note users can supply negative and/or positive infinity objects in
133
- initialising {Rangeary} object, corresponding to the range objects
134
- they give. In default they are the type of either {Float::INFINITY} or
135
- {RangeExtd::Infinity::POSITIVE}. See {Rangeary.new} for detail.
149
+ Note +RangeExtd+ (or +Range+) objects used to initialise {Rangeary}
150
+ instances can contain negative and/or positive infinity objects.
151
+ Since Ruby 2.6 the latter is called {Endless Range}[https://rubyreferences.github.io/rubychanges/2.6.html#endless-range-1]
152
+ and is supported as built-in Range. The former is defined only in
153
+ {RangeExtd}[https://rubygems.org/gems/range_extd] class.
154
+ In default they are of the type of either +Float::INFINITY+ or
155
+ either of the two instances of
156
+ {RangeExtd::Infinity}[https://www.rubydoc.info/gems/range_extd/RangeExtd/Infinity]
157
+ class, +POSITIVE+ or +NEGATIVE+. See {Rangeary.new} for detail about
158
+ how to initialise.
136
159
 
137
160
  When multiple ranges are given in initialising, they are sorted in
138
- storing, and if there is any overlap among any of the elements, they
161
+ storing, and if there are any overlaps among any of the elements, they
139
162
  are treated as disjunction (that is, simple summation). That means
140
163
  the objects a {Rangeary} instance holds internally can be different from
141
- the objects given in initialisation, that is, their {#object_id} may be
164
+ the objects given in initialisation, namely, their {#object_id} may be
142
165
  different. In particular, if built-in Range objects are given,
143
- they are always converted into {RangeExtd} objects internally.
166
+ they are always converted into RangeExtd objects internally.
144
167
 
145
168
  If any of the given range in the intialisation is empty, that is,
146
- {Range#empty?} returns true, they are ignored, unless all of the
169
+ +Range#empty?+ returns true, they are ignored, unless all of the
147
170
  ranges given are empty ranges, in which case the "smallest" one will be
148
171
  preserved.
149
172
 
150
173
  If the result of the operation is empty, only the element of the
151
- resultant {Rangeary} is {RangeExtd::NONE}, and hence
174
+ resultant {Rangeary} is +RangeExtd::NONE+, and hence
152
175
  {Rangeary#empty_element?} will return true.
153
176
 
154
177
  For any Rangeary objects, {Rangeary#to_a}.size is always
155
178
  positive and not zero for that reason, or {Rangeary#empty?} returns
156
- always false, as {Rangeary#empty?} is a method inherited from Array
157
- (Use {Rangeary#empty_element?} instead to check if the instance is
158
- empty or not as a range).
179
+ always false, as {Rangeary#empty?} is a method inherited from Array.
180
+ Use {Rangeary#empty_element?} instead to check whether the instance is
181
+ *practically* empty or not as a range.
182
+
159
183
  Rangeary(RangeExtd::NONE).empty? # => false
160
184
  Rangeary(RangeExtd::NONE).empty_element? # => true
161
185
 
162
- As mentioned above, all the methods of Array but a few are inherited
186
+ As mentioned, all the methods of Array but a few are inherited
163
187
  to this {Rangeary} class, and they work based on each element
164
- {RangeExtd}. Four methods work differently: {Rangeary#+} and
188
+ RangeExtd. Four methods work differently: {Rangeary#+} and
165
189
  {Rangeary#*} are the alias to {Rangeary#disjunction} and
166
190
  {Rangeary#conjunction}, repectively. {Rangeary#===} performs
167
- {Range#===} for all the Rangeary element ranges and return true if any
191
+ +Range#===+ for all the Rangeary element ranges and return true if any
168
192
  of them returns true. Therefore, {Rangeary#===}(RangeExtd(**))
169
- returns always false. {Rangeary#flatten} returns the concatnated
170
- array of {Rangeary#to_a} for all the range elements. Also, [#length]
171
- and [#reverse] are undefined.
172
-
173
- {Rangeary#==} and {Rangeary#eql?} work the same as Array, hence
174
- [2..4, 6..8] == Rangeary(2..4, 6..8) # => true
175
- But please note
176
- [2..4, 6..8] == Rangeary(6..8, 2..4) # => true
177
- [6..8, 2..4] == Rangeary(6..8, 2..4) # => false
178
- In short the direct comparison with a standard Array is not recommended.
179
- Instead compare with other {Rangeary} objects.
193
+ returns always false. Also, +#length+
194
+ and +#reverse+ are undefined. Finally, {Array#==} is modified (see below).
180
195
 
181
196
  All the other methods operating on the element of ranges, rather than
182
197
  on the ranges themselves, have a suffix of <tt>_element</tt>, if there
183
198
  is the same method name in the built-in Array. For example,
184
- {Rangeary#size} returns the number of {RangeExtd} objects it holds,
185
- and {Rangeary#size_element} returns the total {Range#size} of all
186
- the {RangeExtd} objects it holds.
199
+ {Rangeary#size} returns the number of RangeExtd objects it holds,
200
+ and {Rangeary#size_element} returns the total +Range#size+ of all
201
+ the RangeExtd objects it holds.
202
+
187
203
  Rangeary(1..3, 5..8).size # => 2
188
204
  Rangeary(1..3, 5..8).size_element # => 7
189
205
 
206
+ Or, {Rangeary#flatten_element} returns the concatnated
207
+ single array of {Rangeary#to_a} for all the discrete range elements
208
+ (the element ranges have to be discrete like Integer).
209
+
210
+ The complete reference of the class and methods is available at
211
+ {Rubygems website}[http://rubygems.org/gems/rangeary], or you can compile the
212
+ reference with +yard+ from the source package (+make doc+ at the
213
+ package root directory would do).
214
+
215
+ === Array#==
216
+
217
+ Equal method of +Rangeary#==+ should work differently from Array.
218
+ First, it behaves differently for *empty* objects, as Rangeary objects are
219
+ never empty in the sense of Array. Second, handling of
220
+ {Endless Range}[https://rubyreferences.github.io/rubychanges/2.6.html#endless-range-1]
221
+ introduced in Ruby 2.6 is conceptionally not straightforward.
222
+ For example, in Ruby 2.6,
223
+
224
+ (?a..).size # => nil
225
+ (10..).size # => Infinity
226
+ (10..Float::INFINITY)).size # => Infinity
227
+ (1.0..) != (1.0..Float::INFINITY)
228
+
229
+ These are not trivial, or even a little inconsistent. For Range#size method, if it is for
230
+ Numeric (but Complex), Endless Range behaves like the number Infinity,
231
+ yet they (the mathematical infinity and the end of Endless Range) do
232
+ not compare, and are not equal.
233
+
234
+ Rangeary offers functions of logical operations of arrays of Ranges.
235
+ A consistent definitions of infinity is essential. For example, the
236
+ negation of +[5..Infinity]+ is
237
+
238
+ [-Infinity...5]
239
+
240
+ that is, from the negative infinity to 5, excluding the end. Then the
241
+ negation of it must recover the original Rangeary +(5..Infinity)+.
242
+
243
+ Obviously, it could not be done with +Endless Range+, as it defines only the positive infinity,
244
+ or more accurately *positive endlessness*. For that reason, the use of
245
+ +RangeExtd+ is crucial for Rangeary.
246
+
247
+ In the Rangeary operation (of negation in this case), the following can happen:
248
+
249
+ r1 = Rangeary(5..) # => [(5..)] (equivalent to (5..nil))
250
+ r2 = ~Rangeary(5..) # => [(-Float::INFINITY...5)]
251
+ r3 = ~~Rangeary(5..) # => [(5..Float::INFINITY)]
252
+
253
+ r4 = Rangeary(?a..) # => [(?a..)] (equivalent to (?a..nil))
254
+ r5 = ~Rangeary(?a..) # => [(RangeExtd::Infinity::NEGATIVE...?a)]
255
+ r6 = ~~Rangeary(?a..) # => [(?a..RangeExtd::Infinity::POSITIVE)]
256
+
257
+ There is no reason for this operation to result in the (Ruby-2.6) Endless Range
258
+ that began with, after the negation operation from the negative infinity.
259
+ Nevertheless, +r1==r3+ and +r4==r6+ must hold.
260
+
261
+ +RangeExtd#==+ behaves in an almost identical way to +Range#==+
262
+ (except it has +exclude_begin+), such as,
263
+
264
+ (1.0..) != (1.0..Float::INFINITY)
265
+ RangeExtd(1.0..) != RangeExtd(1.0..Float::INFINITY)
266
+
267
+ To maintain the mathematical consistency, Rangeary needs modify the
268
+ equal operator so +r1==r3+ and +r4==r6+ hold, as the standard equal operator of Array would not do the job.
269
+ Hence, Rangeary now regards an Endless Range and a Range that ends with another Infinity
270
+ as equal, as long as all the other Range parameters like the "begin"
271
+ and +exclude_end+ are equal.
272
+
273
+ In practice, +Array#==+ is modified in
274
+ this library (which is naturally inherited to Rangeary), and hence the
275
+ commutativity of the equal operator is assured.
276
+
277
+ Note that +Rangeary#equiv+ method may behave differently from the equal operator.
278
+ For example,
279
+
280
+ Rangeary(RangeExtd(1,"<...",4), 5...8).equiv?(Rangeary(2..3, 5..7))
281
+
282
+ returns true. To describe this, this left and right Rangearies are arrays of
283
+ ranges of Integers which consist of
284
+
285
+ * (Left)
286
+ 1. Range that starts at, but excluding, 1, ending at, but excluding 4
287
+ 2. Range that starts at 5 (inclusive), ending at 8 (exclusive).
288
+ * (Right)
289
+ 1. Range that starts and ending at 2 and 3, respectively, both inclusive.
290
+ 2. Range that starts and ending at 5 and 7, respectively, both inclusive.
291
+
292
+ According to +Integer#succ+ (+Range#each+) method, the left and right ones are equivalent.
293
+ Therefore +Rangeary#equiv+ returns true, wheras the equal operator
294
+ returns false for this.
295
+
296
+ === Infinities
297
+
298
+ The infinities are vital in the logical operation of Rangeary. In
299
+ default, the general infinities of
300
+ <tt>RangeExtd::Infinity::POSITIVE</tt> and <tt>RangeExtd::Infinity::NEGATIVE</tt>
301
+ are used (see ({RangeExtd}[http://rubygems.org/gems/range_extd] for
302
+ detail), except for comparable Numerics (Integer, Rational, Float
303
+ etc), for which +Float::INFINITY is used in default. However, a user
304
+ can specify their own infinities in initialisation with the options of
305
+ +positive:+ and +negative:+.
306
+
307
+ Note once an infinity is defined for a Rangeary object, any other
308
+ Rangeary objects with which operations are performed should have the
309
+ same infinities. In default, if different infinities are specified
310
+ (or if only one of them has a pair of specified infinities and the
311
+ others have the default values), the values that is smallest for the
312
+ Positive infinity and largest for the Negative are used, though a
313
+ warning may be issued (only if the built-in global variable +$VERBOSE+
314
+ is true). An exception is when a user explicitly specifies the infinities in the
315
+ option in creating a new Rangeary out of other Rangeary objects and else, in which case the infinities from the
316
+ other "inherited" Rangeary included in the main parameter are ignored.
317
+
318
+ The last example above shows how it works.
190
319
 
191
320
  == Known bugs
192
321
 
193
322
  * None is known.
194
323
 
195
- This library requires Ruby 2.0 or above (it may work all right with
324
+ This library requires Ruby 2.1 or above (it may work all right with
196
325
  Ruby 1.9.3, however I have never tested it).
197
326
 
198
327
  Extensive tests have been performed, as included in the package.
@@ -203,7 +332,7 @@ Extensive tests have been performed, as included in the package.
203
332
  Nothing planned.
204
333
 
205
334
 
206
- == Final notes
335
+ == Final comment
207
336
 
208
337
  This work is inspired by Ian Stewart, who developped a (numeric)
209
338
  multiple-range library in Fortran90 for the SAS software package for
@@ -212,7 +341,8 @@ XMM-Newton telescope. I appreciate his work.
212
341
  The implementation to Ruby was not straightforward, though, partly
213
342
  because the built-in Range does not allow to exclude the begin
214
343
  boundary, and partly because the infinity is not defined for general
215
- objects but Numeric (Real) in Ruby. {RangeExtd} class I have developed
344
+ objects but Numeric (Real) in Ruby (which later changed partially with
345
+ the introduction of Endless Range in Ruby 2.6 released in 2018 December). RangeExtd class I have developed
216
346
  makes this library possible. I am glad the completeness of ranges in
217
347
  the 1-dimensional space for arbitrary Comparable object is achieved now.
218
348
 
@@ -224,22 +354,22 @@ Enjoy.
224
354
 
225
355
  == Copyright etc
226
356
 
227
- Author:: Masa Sakano < imagine a_t sakano dot co dot uk >
357
+ Author:: Masa Sakano < info a_t wisebabel dot com >
228
358
  License:: MIT.
229
359
  Warranty:: No warranty whatsoever.
230
360
  Versions:: The versions of this package follow Semantic Versioning (2.0.0) http://semver.org/
231
361
 
232
-
362
+ -------------------------------------------
233
363
 
234
364
  = Rangeary - 複数Range(Extd)クラス
235
365
 
236
- このパッケージは、1次元の任意の数のレンジ({RangeExtd} オブジェクト)を
366
+ このパッケージは、1次元の任意の数のレンジ({RangeExtd}[http://rubygems.org/gems/range_extd] オブジェクト)を
237
367
  保持する Rangeary クラスを定義しています。たとえば、<tt>x</tt> に
238
368
  対する複数レンジの
239
369
  0.5 < x <= 2.5, 6.0 <= x < 8.0, 10.0 <= x (<= 無限大)
240
370
  がこのクラスで定義できます。
241
371
 
242
- {RangeExtd} の要素たり得るオブジェクトは全て {Rangeary} の要素となり
372
+ RangeExtd の要素たり得るオブジェクトは全て {Rangeary} の要素となり
243
373
  得ます。Numeric(の実数)に限らず、Comparable であるオブジェクトは全て
244
374
  可能です。また、{Rangeary} は、組込Rangeクラスのオブジェクトも初期化に
245
375
  使えます。
@@ -253,7 +383,7 @@ Versions:: The versions of this package follow Semantic Versioning (2.0.0) http:
253
383
  {Rangeary} オブジェクトはイミュータブルです。すなわち、
254
384
  一度インスタンスが生成されると、要素を書換えることはできません。
255
385
 
256
- 実用的には、{Rangeary} は、Arrayのサブクラスとなっていて、{RangeExtd}
386
+ 実用的には、{Rangeary} は、Arrayのサブクラスとなっていて、RangeExtd
257
387
  の配列として振舞います。また、Arrayのほとんどのメソッドを継承していま
258
388
  す。したがって、イミュータブルな{Rangeary}に許される限りにおいて、
259
389
  Arrayに使えるほとんどの操作を{Rangeary}に適用できます。加えて、
@@ -267,7 +397,7 @@ Arrayに使えるほとんどの操作を{Rangeary}に適用できます。加
267
397
 
268
398
  == インストール
269
399
 
270
- まず、{RangeExtd} クラスのライブラリ(純粋に rubyで書かれたファイル 2個
400
+ まず、RangeExtd クラスのライブラリ(純粋に rubyで書かれたファイル 2個
271
401
  です)が必要です。gem を使ってインストールできます。
272
402
  gem install range_extd
273
403
  もしくは以下から入手して下さい。
@@ -286,12 +416,10 @@ http://rubygems.org/gems/rangeary
286
416
  require 'rangeary/rangeary'
287
417
  とするだけです。もしくは、特に手でインストールした場合は、
288
418
  require 'rangeary'
289
- とする必要があるかも知れません。他のファイル({RangeExtd} 用の
419
+ とする必要があるかも知れません。他のファイル(RangeExtd 用の
290
420
  <tt>range_extd/range_extd.rb</tt>)は、自動的に読込まれます。
291
421
 
292
- {Rangeary} 自体は Ruby 1.8でも動作するかも知れません。しかし、
293
- {RangeExtd} が Ruby 2.0 (ひょっとしたら 1.9.3)以上でしか動かないため、
294
- 実質的には {Rangeary} は Ruby 1.8 以前のバージョンでは動作しません。
422
+ {Rangeary} Ruby 2.1 以上で動きます。
295
423
 
296
424
  お楽しみあれ!
297
425
 
@@ -309,8 +437,8 @@ http://rubygems.org/gems/rangeary
309
437
  Rangeary(true..true) # => ArgumentError
310
438
 
311
439
  基本的に、<tt>Rangeary()</tt> または <tt>Rangeary.new()</tt> は、任意
312
- の数の {Range}{RangeExtd}、{Rangeary} あるいはその組合わせを引数とし
313
- て取ります。ただし、{Range}クラスのオブジェクトで {Range#valid?} が偽
440
+ の数の Range、RangeExtd、{Rangeary} あるいはその組合わせを引数とし
441
+ て取ります。ただし、Rangeクラスのオブジェクトで +Range#valid?+ が偽
314
442
  を返すものは、例外が発生します。
315
443
 
316
444
  さらなる解説及び例は、{Rangeary.new}を参照して下さい。
@@ -333,9 +461,16 @@ http://rubygems.org/gems/rangeary
333
461
  rb + Rangeary(3..7) # => [2...9]
334
462
  rb - Rangeary(3..7) # => [2...3, RangeExtd(7,'<...',9)]
335
463
  rb * Rangeary(4..5, 8..10) # => [4..4, 8...9]
336
- rb.negation # => [-Float::INFINITY...2, RangeExtd(4,'<...',6), 9..Float::INFINITY]
464
+ ~rb # => [-Float::INFINITY...2, RangeExtd(4,'<...',6), 9..Float::INFINITY]
337
465
 
338
- 組込Arrayクラスに含まれるほとんどのメソッドが、たとえば{Array#push}のように
466
+ rc = Rangeary(?d...?x, negative: ?a, positive: ?z)
467
+ ~rc # => [?a...?d, ?x..?z]
468
+
469
+ ここで、+~rb+ は +rb.negation+ と等価で論理否定を意味します。最後の例
470
+ では、ユーザー指定の*無限大/無限小*値を定義しています。
471
+
472
+
473
+ 組込Arrayクラスに含まれるほとんどのメソッドが、たとえば+Array#push+のように
339
474
  {Rangeary} がイミュータブルであることに抵触しない限りにおいて、使用可能です。
340
475
 
341
476
 
@@ -354,13 +489,13 @@ http://rubygems.org/gems/rangeary
354
489
  す。だから、一度インスタンスが生成されると、変化しません。
355
490
 
356
491
  インスタンスの生成方法は上述の通りです(「使用例」の章)。レンジとして"valid"と見
357
- なされないインスタンスを生成しようとすると、すなわち {Range#valid?}
492
+ なされないインスタンスを生成しようとすると、すなわち +Range#valid?+
358
493
  偽を返すレンジを使おうとすると、例外(<tt>ArgumentError</tt>)が発生し、
359
494
  失敗します。
360
495
 
361
496
  なお、ユーザーは、{Rangeary} インスタンス生成の時、レンジ要素に対応し
362
497
  た正負の無限大オブジェクトを付加することができます。デフォルトでは、
363
- {Float::INFINITY} または {RangeExtd::Infinity::POSITIVE} の類に
498
+ +Float::INFINITY+ または +RangeExtd::Infinity::POSITIVE+ の類に
364
499
  なります。詳しくは {Rangeary.new} を参照下さい。
365
500
 
366
501
  生成時に複数のレンジが引数として与えられた時、ソートされて保持されます。
@@ -368,14 +503,14 @@ http://rubygems.org/gems/rangeary
368
503
  (つまり、単純に足し合わされます)。これはつまり、{Rangeary} が内部的に
369
504
  保持するオブジェクトは生成時に与えられたものとは異なる、すなわち
370
505
  {#object_id} が異なるかも知れないことを意味します。特に、組込Rangeが引
371
- 数として与えられた時は、常に {RangeExtd} オブジェクトに内部で変換されます。
506
+ 数として与えられた時は、常に RangeExtd オブジェクトに内部で変換されます。
372
507
 
373
- もし生成時に与えられたレンジのどれかが空、すなわち {Range#empty?} が真
508
+ もし生成時に与えられたレンジのどれかが空、すなわち +Range#empty?+ が真
374
509
  を返す場合、それらは無視されます。ただし、引数の全てのレンジが空であっ
375
510
  た場合は、「最小」のものが残されます。
376
511
 
377
512
  もし演算の結果として空の{Rangeary}が返される場合、その唯一の要素は
378
- {RangeExtd::NONE}となり、したがって
513
+ +RangeExtd::NONE+となり、したがって
379
514
  {Rangeary#empty_element?} が真を返します。
380
515
 
381
516
  そのため、どの Rangeary オブジェクトも、{Rangeary#to_a}.size は常に正
@@ -386,14 +521,13 @@ http://rubygems.org/gems/rangeary
386
521
  Rangeary(RangeExtd::NONE).empty_element? # => true
387
522
 
388
523
  前述のように、ごく一部を除いた全ての Arrayクラスのメソッドがこの
389
- {Rangeary} クラスに継承されていて、それらは各{RangeExtd}要素に対して
524
+ {Rangeary} クラスに継承されていて、それらは各RangeExtd要素に対して
390
525
  動作します。ただし、4個のメソッドの挙動が異なります。
391
526
  {Rangeary#+} と {Rangeary#*} とは、それぞれ {Rangeary#disjunction} と
392
527
  {Rangeary#conjunction} とへのエイリアスとなっています。{Rangeary#===}
393
- は、全ての{RangeExtd}要素に対して{Range#===}を実行し、それらの一つでも
528
+ は、全てのRangeExtd要素に対して+Range#===+を実行し、それらの一つでも
394
529
  真を返せば真を返します。したがって、{Rangeary#===}(RangeExtd(**))は常
395
- に偽を返します。{Rangeary#flatten} は、全ての{RangeExtd}要素に対して
396
- {Rangeary#to_a} を実行して、その結果を結合した配列を返します。
530
+ に偽を返します。
397
531
  また、[#length] と [#reverse] とは未定義化されています。
398
532
 
399
533
  {Rangeary#==} と {Rangeary#eql?} は、Arrayと同様に動作します。だから
@@ -407,19 +541,131 @@ http://rubygems.org/gems/rangeary
407
541
  レンジ要素に対してではなく、レンジを構成する要素に対して動作する他の
408
542
  全てのメソッドは、組込Arrayクラスに同名のメソッドが存在する場合、接尾辞
409
543
  <tt>_element</tt> がつきます。たとえば、{Rangeary#size} は、保持する
410
- {RangeExtd} オブジェクトの数を返し、一方、{Rangeary#size_element}は、
411
- 保持するすべての {RangeExtd}オブジェクトに対して {Range#size} を行った
544
+ RangeExtd オブジェクトの数を返し、一方、{Rangeary#size_element}は、
545
+ 保持するすべての RangeExtdオブジェクトに対して +Range#size+ を行った
412
546
  その総和を返します。
413
547
  Rangeary(1..3, 5..8).size # => 2
414
548
  Rangeary(1..3, 5..8).size_element # => 7
415
549
 
550
+ {Rangeary#flatten_element} は、全てのRangeExtd要素に対して
551
+ {Rangeary#to_a} を実行して、その結果を結合した配列を返します。
552
+
553
+ クラスとメソッドの完全なマニュアルは、
554
+ {Rubygems のウェブサイト}[http://rubygems.org/gems/rangeary]上にあります。
555
+ あるいは、ソースパッケージを展開して、ルートディレクトリで +make doc+
556
+ することで、手元でコンパイルすることもできます(RubyGems の +yard+
557
+ がインストールされている必要があります)。
558
+
559
+ === Array#==
560
+
561
+ 等号メソッド +Rangeary#==+ は、Array とは異なった挙動をするべきであり、
562
+ 実際します。まず、*empty?* の際の意味が、異なります。なぜならば、
563
+ Rangeary オブジェクトは、Array的な意味では、empty になることは決してな
564
+ いからです。次に、Ruby 2.6で導入された
565
+ {Endless Range}[https://rubyreferences.github.io/rubychanges/2.6.html#endless-range-1]
566
+ は、概念的にそう素直には組み込まれません。例えば、Ruby 2.6 では以下の
567
+ ような挙動を示します。
568
+
569
+ (?a..).size # => nil
570
+ (10..).size # => Infinity
571
+ (10..Float::INFINITY)).size # => Infinity
572
+ (1.0..) != (1.0..Float::INFINITY)
573
+
574
+ これらは、当たり前の挙動ではありませんし、若干矛盾があるとさえ言えるかも
575
+ 知れません。Range#size メソッドに関しては、Numericクラス(Complexを除く)
576
+ のオブジェクトに関しては、Endless Range は、数学的無限のように振舞いま
577
+ す。しかし、両者を比較することはできず、等号比較すると、偽が返ります。
578
+
579
+ Rangeary は、複数の Range からなる数列(array)に対して、論理演算する機
580
+ 能を提供します。そのためには、一貫した「無限」の定義が不可欠です。例え
581
+ ば、 +[5..Infinity]+ の否定は、
582
+
583
+ [-Infinity...5]
584
+
585
+ すなわち、無限小から始まり、5 で終わるが、終端は含まれない、ということ
586
+ になります。これに対して再度否定演算を行うと、元の Rangeary +(5..Infinity)+
587
+ が再度得られなければなりません。
588
+
589
+ この演算は、当然、+Endless Range+ だけでは不可能です。+Endless Range+
590
+ は正の無限大、あるいは正確には、正の方向に開いたもの、しか定義していないからです。
591
+ このため、+RangeExtd+ を使用することは、Rangeary では決定的に重要なの
592
+ です。
593
+
594
+ Rangearyの演算(ここでは否定演算)においては、以下のようになります。
595
+
596
+ r1 = Rangeary(5..) # => [(5..)] (equivalent to (5..nil))
597
+ r2 = ~Rangeary(5..) # => [(-Float::INFINITY...5)]
598
+ r3 = ~~Rangeary(5..) # => [(5..Float::INFINITY)]
599
+
600
+ r4 = Rangeary(?a..) # => [(?a..)] (equivalent to (?a..nil))
601
+ r5 = ~Rangeary(?a..) # => [(RangeExtd::Infinity::NEGATIVE...?a)]
602
+ r6 = ~~Rangeary(?a..) # => [(?a..RangeExtd::Infinity::POSITIVE)]
603
+
604
+ この演算において、負の無限大も経過した最後の結果が、元々の出発点である(Ruby2.6で言う)
605
+ Endless Rangeにならなければいけない理由はないことになります。しかしながら、
606
+ +r1==r3+ および +r4==r6+ は成立すべきです。
607
+
608
+ +RangeExtd#==+ は、+Range#==+ とほぼ同一に振舞います(前者は
609
+ +exclude_begin+ メソッドを持つことを除いて)。例えば、
610
+
611
+ (1.0..) != (1.0..Float::INFINITY)
612
+ RangeExtd(1.0..) != RangeExtd(1.0..Float::INFINITY)
613
+
614
+ +r1==r3+ や +r4==r6+ も成立するよう、数学的一貫性を保つために、Rangeary では、
615
+ 等号の定義を変更する必要がありました。Array クラスのデフォルトの標準等
616
+ 号ではダメだからです。
617
+ そこで、Rangeary では、Endless Range と終端が何か別の無限大である
618
+ Rangeとは、他のパラメーター(例えば始端や+exclude_end+)が等しい限り、等
619
+ しいと見なします。
620
+
621
+ 実装としては、本ライブラリ内で +Array#==+ (Rangearyに自然に継承される)を変更しています。
622
+ そのため、等号の可換性が保たれています。
623
+
624
+ なお、+Rangeary#equiv+ メソッドは、等号とは異なる挙動をすることがあり
625
+ ます。例えば、
626
+
627
+ Rangeary(RangeExtd(1,"<...",4), 5...8).equiv?(Rangeary(2..3, 5..7))
628
+
629
+ は真になります。以下のような説明になります。左右の Rangearyは、整数の
630
+ Rangeからなる配列で、
631
+
632
+ * (左側の Rangeary)
633
+ 1. 始端が1 (但し始端自体は含まない)で、終端が4 (但し終端自体は含まない)
634
+ 2. 始端が5 (始端を含む)で、終端が8 (但し終端自体は含まない)
635
+ * (右側の Rangeary)
636
+ 1. 始端が2、終端が3 (両端を含む)
637
+ 2. 始端が5、終端が7 (両端を含む)
638
+
639
+ +Integer#succ+ (あるいは、+Range#each+)メソッド的には、左側と右側とは等価です。したがって、
640
+ +Rangeary#equiv+ でこの両者を比較すると真を返します。一方、等号は負を
641
+ 返します。
642
+
643
+ === 無限大
644
+
645
+ 正負の無限大は、Rangearyの演算に不可欠です。デフォルトでは、正負の一般無限大は
646
+ <tt>RangeExtd::Infinity::POSITIVE</tt> と <tt>RangeExtd::Infinity::NEGATIVE</tt>
647
+ が使われます(詳細は {RangeExtd}[http://rubygems.org/gems/range_extd] 参照)。
648
+ 但し、例外が、比較可能な Numerics (Integer, Rational, Floatなど)で、
649
+ +Float::INFINITY がデフォルトで使われます。しかし、ユーザーは、オブジェ
650
+ クト作成の時、+positive:+ および +negative:+ で自分の無限大を定義することもできます。
651
+
652
+ なお、一旦、無限大が定義されると、そのオブジェクトと演算を行う全ての
653
+ Rangearyオブジェクトも同じ無限大をもつべきです。デフォルトでは、演算す
654
+ るオブジェクト間でもし異なる無限大が使われている場合(端的には、一つの
655
+ オブジェクトにだけ無限大を定義して他はデフォルトで済ませている場合)は、
656
+ 正の無限大には最小の値、負の無限大には最大の値が選ばれます。但し、警告
657
+ メッセージが出るかもしれません(組込グローバル変数 +$VERBOSE+が真の時のみ)。
658
+ 例外は、複数のRangearyから新しいRangeryオブジェクトを作成の際に、オプ
659
+ ションで陽に無限大を指定した時で、その時は、それらRangearyから継承した
660
+ 値は考慮されず、指定した値が使われます。
661
+
662
+ 上記の最後の例が、指定する例です。
416
663
 
417
664
  == 既知のバグ
418
665
 
419
666
  * 無し。
420
667
 
421
- このライブラリは Ruby 2.0 以上を必要とします(Ruby 1.9.3 では動くかも
422
- 知れませんが、私は試したことがありません)。
668
+ このライブラリは Ruby 2.1 以上を必要とします。
423
669
 
424
670
  パッケージに含まれている通り、網羅的なテストが実行されています。
425
671
 
@@ -438,7 +684,7 @@ Fortran90ライブラリにアイデアを得たものです。彼の仕事に
438
684
  しかし、Rubyへの実装は、一筋縄ではいきませんでした。一つには組込Range
439
685
  クラスでは始点を除外することができないこと、また一つには Rubyでは数値
440
686
  を除いて一般オブジェクトに対しての無限大が定義されていないからです。
441
- 小生の開発した {RangeExtd} によって初めてこのライブラリが可能となりま
687
+ 小生の開発した RangeExtd によって初めてこのライブラリが可能となりま
442
688
  した。これにより、今、比較可能な任意のオブジェクトについて、1次元上の
443
689
  レンジの完全性が実現できたことを嬉しく思います。
444
690
 
@@ -449,7 +695,7 @@ Fortran90ライブラリにアイデアを得たものです。彼の仕事に
449
695
 
450
696
  == 著作権他情報
451
697
 
452
- 著者:: Masa Sakano < imagine a_t sakano dot co dot uk >
698
+ 著者:: Masa Sakano < info a_t wisebabel dot com >
453
699
  利用許諾条項:: MIT.
454
700
  保証:: 一切無し。
455
701
  バージョン:: Semantic Versioning (2.0.0) http://semver.org/