range_extd 1.0 → 1.1
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/ChangeLog +12 -12
- data/News +4 -0
- data/README.en.rdoc +52 -21
- data/README.ja.rdoc +27 -18
- data/lib/range_extd/infinity/infinity.rb +264 -56
- data/lib/range_extd/range_extd.rb +67 -13
- data/test/test_range_extd.rb +162 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ef735cf8d777f8f86ab2a5d3654577f06f0b41abf796c5c7147bc23482741dc
|
4
|
+
data.tar.gz: 33cf0bf6894c7de27b3c2714c03ba3042235751bd2bbeb506c0105c66badd110
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2240719d2e3f7f7933cea2e6b03268b87f0357526851b8a54b1645a320b35a44027808063df2176bbe4ac51ffacc91d517c5999c9c382244ab99a29219bbf795
|
7
|
+
data.tar.gz: 32f5f4b3cc81aee0bb099a33a6c905e713896eb875dc749cbb6365243f3f81eebfaf75604031a328faa31bbdcc8466956182cef03fe12d4b5d4d2f6fb59db810
|
data/ChangeLog
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
-----
|
2
|
-
(Version: 1.
|
3
|
-
2019-
|
4
|
-
*
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
(
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
2
|
+
(Version: 1.1)
|
3
|
+
2019-11-01 Masa Sakano
|
4
|
+
* Significant upgrade: RangeExtd
|
5
|
+
* size of RangeExtd with an infinity now follows what Ruby Endless Range returns.
|
6
|
+
* Example: (?a..RangeExtd::Infinity::POSITIVE).size used to be Float::INFINITY, but now nil.
|
7
|
+
* RangeExtd::Infinity::POSITIVE etc now replaced with Float::INFINITY when it should be.
|
8
|
+
* RangeExtd::Infinity
|
9
|
+
* POSITIVE (or NEGATIVE) and Float::INFINITY are now NOT comparable. Description added to README.
|
10
|
+
* Newly redefined methods of ">" and "<" for RangeExtd::Infinity, as otherwise the comparison with Numeric fails as of Ruby 2.6 (I do not know whether it has been so or it has changed in recent versions of Ruby)
|
11
|
+
* New class methods of Infinity.infinity? and Infinity.infinite? in which the former excludes Float::INFINITY whereas the latter includes.
|
12
|
+
* Two unary operators (plus and minus) now supported.
|
13
|
+
* The methods "=", ">" and "<" redefined for Float and Integer (hence Rational) so they can be compared with this.
|
14
14
|
|
15
15
|
-----
|
16
16
|
(Version: 1.0)
|
data/News
CHANGED
data/README.en.rdoc
CHANGED
@@ -68,14 +68,7 @@ I hope you find this package to be useful.
|
|
68
68
|
=== News: Endless Range supported
|
69
69
|
|
70
70
|
Now, as of 2019 October, this fully supports {Endless Range}[https://rubyreferences.github.io/rubychanges/2.6.html#endless-range-1]
|
71
|
-
introduced in Ruby 2.6. It is released as Version 1
|
72
|
-
|
73
|
-
==== NOTE: Relationship with Rangesmaller
|
74
|
-
|
75
|
-
This package supersedes the obsolete {Rangesmaller}[https://rubygems.org/gems/rangesmaller] package and class,
|
76
|
-
with the added open-ended feature, and a different interface in
|
77
|
-
creating a new instance.
|
78
|
-
https://rubygems.org/gems/rangesmaller
|
71
|
+
introduced in Ruby 2.6. It is released as Version 1.* finally!
|
79
72
|
|
80
73
|
==== NOTE: Relationship with Rangeary
|
81
74
|
|
@@ -83,8 +76,20 @@ The class to handle multiple Ranges with objects of the same class
|
|
83
76
|
(most typically Float),
|
84
77
|
{Rangeary}[https://rubygems.org/gems/rangeary] uses this library to
|
85
78
|
fullest, because the concept of potentially open-ended Range on both
|
86
|
-
begin and end is essential to realise
|
87
|
-
|
79
|
+
begin and end is essential to realise it. For example, the negation
|
80
|
+
of Range +(?a..?d)+ is Ranges +(-"Infinity-Character"...3)+ and
|
81
|
+
+(?d(exclusive).."Infinity-Character")+ and its negation is back to
|
82
|
+
the original +(?a..?d)+. Such operations are possible only with this
|
83
|
+
class +RangeExtd+
|
84
|
+
|
85
|
+
Rangeary: https://rubygems.org/gems/rangeary
|
86
|
+
|
87
|
+
==== NOTE: Relationship with Rangesmaller
|
88
|
+
|
89
|
+
This package RangeExtd supersedes the obsolete {Rangesmaller}[https://rubygems.org/gems/rangesmaller] package and class,
|
90
|
+
with the added open-ended feature, and a different interface in
|
91
|
+
creating a new instance.
|
92
|
+
https://rubygems.org/gems/rangesmaller
|
88
93
|
|
89
94
|
|
90
95
|
== Install
|
@@ -215,7 +220,7 @@ politely.
|
|
215
220
|
For more detail, see its documents (YARD or RDoc-style
|
216
221
|
documents embedded in the code, or see {RubyGems webpage}[http://rubygems.org/gems/range_extd]).
|
217
222
|
|
218
|
-
**
|
223
|
+
**Note1:** +RangeExtd::Infinity::POSITIVE+ is practically the same as
|
219
224
|
{Endless Range}[https://rubyreferences.github.io/rubychanges/2.6.html#endless-range-1]
|
220
225
|
introduced in Ruby 2.6 released in 2018 December!! In other words,
|
221
226
|
the official Ruby has finally implement a part of this library!
|
@@ -224,6 +229,28 @@ official Ruby Range (it has no "boundless begin"), and hence this library still
|
|
224
229
|
supplements the mathematical incompleteness of the standard Range in
|
225
230
|
the official Ruby.
|
226
231
|
|
232
|
+
**Note2:**
|
233
|
+
As of Ver.1.1, the +RangeExtd::Infinity+ class instances are not
|
234
|
+
comparable with +Float::INFINITY+; for example,
|
235
|
+
|
236
|
+
RangeExtd::Infinity::POSITIVE != Float::INFINITY # => true
|
237
|
+
|
238
|
+
Conceptionally, the former is a generalised object of the latter and
|
239
|
+
hence they should not be *equal*. See the reference of
|
240
|
+
{RangeExtd::Infinity} for detail. Note, the behaviour of Endless Range from Ruby 2.6
|
241
|
+
may feel a little odd, as follows:
|
242
|
+
|
243
|
+
num1 = (5..Float::INFINITY)
|
244
|
+
num2 = (5..)
|
245
|
+
num1.end != rnum2.end # => true
|
246
|
+
num1.size # => Infinity
|
247
|
+
num2.size # => Infinity
|
248
|
+
|
249
|
+
str1 = (?a..)
|
250
|
+
str1.end == num2.end # => true (because both are nil)
|
251
|
+
str1.size # => nil
|
252
|
+
|
253
|
+
|
227
254
|
=== RangeExtd Class
|
228
255
|
|
229
256
|
RangeExtd objects are immutable, the same as Range.
|
@@ -372,7 +399,7 @@ Enjoy.
|
|
372
399
|
|
373
400
|
== Copyright etc
|
374
401
|
|
375
|
-
Author:: Masa Sakano <
|
402
|
+
Author:: Masa Sakano < info a_t wisebabel dot com >
|
376
403
|
License:: MIT.
|
377
404
|
Warranty:: No warranty whatsoever.
|
378
405
|
Versions:: The versions of this package follow Semantic Versioning (2.0.0) http://semver.org/
|
@@ -448,6 +475,18 @@ Versions:: The versions of this package follow Semantic Versioning (2.0.0) http:
|
|
448
475
|
2019年10月より、本パッケージは、Ruby 2.6 で導入された {Endless Range}[https://rubyreferences.github.io/rubychanges/2.6.html#endless-range-1]
|
449
476
|
(終端のない Range)を正式サポートしました。よって、Version 1.0 をリリースしました!
|
450
477
|
|
478
|
+
==== 注: Rangearyとの関係
|
479
|
+
|
480
|
+
同クラス(典型的にはFloat)のオブジェクトからなる複数のRangeを扱うクラス
|
481
|
+
{Rangeary}[https://rubygems.org/gems/rangeary] は、本ライブラリを使い
|
482
|
+
切っています。Rangeを実現するためには、始端と終端との両方で開いた可能
|
483
|
+
性があるRangeを扱うことが必須だからです。例えば、
|
484
|
+
Range +(?a..?d)+ の否定は、複数Range +(-"Infinity(文字)"...3)+ と
|
485
|
+
+(?d(始端除外).."Infinity(文字)")+ であり、その否定は、元の +(?a..?d)+
|
486
|
+
です。このような演算は、+RangeExtd+ があって初めて可能になります。
|
487
|
+
|
488
|
+
Rangeary: https://rubygems.org/gems/rangeary
|
489
|
+
|
451
490
|
==== 注: Rangesmallerとの関係
|
452
491
|
|
453
492
|
このパッケージは、(今やサポートされていない) {Rangesmaller}[https://rubygems.org/gems/rangesmaller] パッケージ及びクラスを
|
@@ -455,14 +494,6 @@ Versions:: The versions of this package follow Semantic Versioning (2.0.0) http:
|
|
455
494
|
ブジェクト生成時のインターフェースが変更されています。
|
456
495
|
https://rubygems.org/gems/rangesmaller
|
457
496
|
|
458
|
-
==== 注: Rangearyとの関係
|
459
|
-
|
460
|
-
同クラス(典型的にはFloat)のオブジェクトからなる複数のRangeを扱うクラス
|
461
|
-
{Rangeary}[https://rubygems.org/gems/rangeary] は、本ライブラリを使い
|
462
|
-
切っています。Rangeを実現するためには、始端と終端との両方で開いた可能
|
463
|
-
性があるRangeを扱うことが必須だからです。
|
464
|
-
https://rubygems.org/gems/rangeary
|
465
|
-
|
466
497
|
== インストール
|
467
498
|
|
468
499
|
gem install range_extd
|
@@ -733,7 +764,7 @@ RangeExtd内部に閉じた(Rangeでなく)挙動、たとえば RangeExtd同士
|
|
733
764
|
|
734
765
|
== 著作権他情報
|
735
766
|
|
736
|
-
著者:: Masa Sakano <
|
767
|
+
著者:: Masa Sakano < info a_t wisebabel dot com >
|
737
768
|
利用許諾条項:: MIT.
|
738
769
|
保証:: 一切無し。
|
739
770
|
バージョン:: Semantic Versioning (2.0.0) http://semver.org/
|
data/README.ja.rdoc
CHANGED
@@ -68,14 +68,7 @@ I hope you find this package to be useful.
|
|
68
68
|
=== News: Endless Range supported
|
69
69
|
|
70
70
|
Now, as of 2019 October, this fully supports {Endless Range}[https://rubyreferences.github.io/rubychanges/2.6.html#endless-range-1]
|
71
|
-
introduced in Ruby 2.6. It is released as Version 1
|
72
|
-
|
73
|
-
==== NOTE: Relationship with Rangesmaller
|
74
|
-
|
75
|
-
This package supersedes the obsolete {Rangesmaller}[https://rubygems.org/gems/rangesmaller] package and class,
|
76
|
-
with the added open-ended feature, and a different interface in
|
77
|
-
creating a new instance.
|
78
|
-
https://rubygems.org/gems/rangesmaller
|
71
|
+
introduced in Ruby 2.6. It is released as Version 1.* finally!
|
79
72
|
|
80
73
|
==== NOTE: Relationship with Rangeary
|
81
74
|
|
@@ -83,8 +76,20 @@ The class to handle multiple Ranges with objects of the same class
|
|
83
76
|
(most typically Float),
|
84
77
|
{Rangeary}[https://rubygems.org/gems/rangeary] uses this library to
|
85
78
|
fullest, because the concept of potentially open-ended Range on both
|
86
|
-
begin and end is essential to realise
|
87
|
-
|
79
|
+
begin and end is essential to realise it. For example, the negation
|
80
|
+
of Range +(?a..?d)+ is Ranges +(-"Infinity-Character"...3)+ and
|
81
|
+
+(?d(exclusive).."Infinity-Character")+ and its negation is back to
|
82
|
+
the original +(?a..?d)+. Such operations are possible only with this
|
83
|
+
class +RangeExtd+
|
84
|
+
|
85
|
+
Rangeary: https://rubygems.org/gems/rangeary
|
86
|
+
|
87
|
+
==== NOTE: Relationship with Rangesmaller
|
88
|
+
|
89
|
+
This package RangeExtd supersedes the obsolete {Rangesmaller}[https://rubygems.org/gems/rangesmaller] package and class,
|
90
|
+
with the added open-ended feature, and a different interface in
|
91
|
+
creating a new instance.
|
92
|
+
https://rubygems.org/gems/rangesmaller
|
88
93
|
|
89
94
|
|
90
95
|
== Install
|
@@ -448,6 +453,18 @@ Versions:: The versions of this package follow Semantic Versioning (2.0.0) http:
|
|
448
453
|
2019年10月より、本パッケージは、Ruby 2.6 で導入された {Endless Range}[https://rubyreferences.github.io/rubychanges/2.6.html#endless-range-1]
|
449
454
|
(終端のない Range)を正式サポートしました。よって、Version 1.0 をリリースしました!
|
450
455
|
|
456
|
+
==== 注: Rangearyとの関係
|
457
|
+
|
458
|
+
同クラス(典型的にはFloat)のオブジェクトからなる複数のRangeを扱うクラス
|
459
|
+
{Rangeary}[https://rubygems.org/gems/rangeary] は、本ライブラリを使い
|
460
|
+
切っています。Rangeを実現するためには、始端と終端との両方で開いた可能
|
461
|
+
性があるRangeを扱うことが必須だからです。例えば、
|
462
|
+
Range +(?a..?d)+ の否定は、複数Range +(-"Infinity(文字)"...3)+ と
|
463
|
+
+(?d(始端除外).."Infinity(文字)")+ であり、その否定は、元の +(?a..?d)+
|
464
|
+
です。このような演算は、+RangeExtd+ があって初めて可能になります。
|
465
|
+
|
466
|
+
Rangeary: https://rubygems.org/gems/rangeary
|
467
|
+
|
451
468
|
==== 注: Rangesmallerとの関係
|
452
469
|
|
453
470
|
このパッケージは、(今やサポートされていない) {Rangesmaller}[https://rubygems.org/gems/rangesmaller] パッケージ及びクラスを
|
@@ -455,14 +472,6 @@ Versions:: The versions of this package follow Semantic Versioning (2.0.0) http:
|
|
455
472
|
ブジェクト生成時のインターフェースが変更されています。
|
456
473
|
https://rubygems.org/gems/rangesmaller
|
457
474
|
|
458
|
-
==== 注: Rangearyとの関係
|
459
|
-
|
460
|
-
同クラス(典型的にはFloat)のオブジェクトからなる複数のRangeを扱うクラス
|
461
|
-
{Rangeary}[https://rubygems.org/gems/rangeary] は、本ライブラリを使い
|
462
|
-
切っています。Rangeを実現するためには、始端と終端との両方で開いた可能
|
463
|
-
性があるRangeを扱うことが必須だからです。
|
464
|
-
https://rubygems.org/gems/rangeary
|
465
|
-
|
466
475
|
== インストール
|
467
476
|
|
468
477
|
gem install range_extd
|
@@ -17,7 +17,9 @@ class RangeExtd < Range
|
|
17
17
|
# Class to hold just two constants:
|
18
18
|
# * RangeExtd::Infinity::NEGATIVE
|
19
19
|
# * RangeExtd::Infinity::POSITIVE
|
20
|
+
#
|
20
21
|
# and two more:
|
22
|
+
#
|
21
23
|
# * FLOAT_INFINITY (OBSOLETE; workaround for Ruby 1.8 to represent Float::INFINITY)
|
22
24
|
# * CLASSES_ACCEPTABLE (see below)
|
23
25
|
#
|
@@ -42,7 +44,7 @@ class RangeExtd < Range
|
|
42
44
|
# There are only three built-in classes that are Comparable: String, Time and Numeric
|
43
45
|
# (except for Complex).
|
44
46
|
# Note Date and DateTime objects are so, too, however practically
|
45
|
-
# they need "require", hence are (and must be) treated, the same as any other
|
47
|
+
# they need "require", hence are (and must be) treated, the same as any other classes.
|
46
48
|
# For String and Time class objects, the [#<=>] operator work as expected
|
47
49
|
# in the commutative way.
|
48
50
|
# ?z <=> RangeExtd::Infinity::POSITIVE # => nil
|
@@ -96,9 +98,43 @@ class RangeExtd < Range
|
|
96
98
|
#
|
97
99
|
# Only the methods defined in this class are
|
98
100
|
# {#===}, {#==}, {#<=>}, {#succ}, {#to_s}, {#inspect},
|
99
|
-
# {#infinity?}, {#positive?} and {#negative?}.
|
101
|
+
# {#infinity?}, {#positive?} and {#negative?}, and in addition, since Version 1.1,
|
102
|
+
# two unary operators {#@+} and {#@-} to unchange/swap the parity are defined
|
103
|
+
# ({#<} and {#>} are modified, too, to deal with Integer and Float;
|
104
|
+
# I do not know whether the default behaviour of these classes have changed
|
105
|
+
# in the recent versions of Ruby, hence resulting in the neccesity of this change).
|
106
|
+
#
|
107
|
+
# === Comparison operators
|
108
|
+
#
|
109
|
+
# {RangeExtd::Infinity::POSITIVE} and InfN {RangeExtd::Infinity::NEGATIVE}
|
110
|
+
# are always comparable with any comparable objects except for
|
111
|
+
# Float::INFINITY, in which case
|
112
|
+
#
|
113
|
+
# (RangeExtd::Infinity::POSITIVE <=> Float::INFINITY) # => nil
|
114
|
+
# (RangeExtd::Infinity::POSITIVE < Float::INFINITY) # => ArgumentError
|
115
|
+
# (RangeExtd::Infinity::POSITIVE > Float::INFINITY) # => ArgumentError
|
116
|
+
# (RangeExtd::Infinity::POSITIVE == Float::INFINITY) # => false
|
117
|
+
#
|
118
|
+
# which is what happens for the comparison operators for Float::INFINITY.
|
119
|
+
#
|
120
|
+
# Basically, the concept of {RangeExtd::Infinity::POSITIVE} is a generalised
|
121
|
+
# concept of Float::INFINITY. Therefore they are really not *equal*.
|
122
|
+
# On the other hand, {RangeExtd::Infinity::POSITIVE} is *greater* than
|
123
|
+
# any normal comparable objects (except those that are *infinite*).
|
124
|
+
# Therefore, all the following are true ({Object#<=>} and some methods
|
125
|
+
# in some classes are modified)
|
126
|
+
#
|
127
|
+
# (5 < RangeExtd::Infinity::POSITIVE)
|
128
|
+
# (5 > RangeExtd::Infinity::NEGATIVE)
|
100
129
|
#
|
101
|
-
#
|
130
|
+
# ("a" < RangeExtd::Infinity::POSITIVE)
|
131
|
+
# ("a" > RangeExtd::Infinity::NEGATIVE)
|
132
|
+
#
|
133
|
+
# whereas
|
134
|
+
#
|
135
|
+
# (RangeExtd::Infinity::POSITIVE < Object.new) # => ArgumentError
|
136
|
+
#
|
137
|
+
# raises ArgumentError.
|
102
138
|
#
|
103
139
|
class Infinity
|
104
140
|
|
@@ -118,9 +154,25 @@ class RangeExtd < Range
|
|
118
154
|
# CLASSES_ACCEPTABLE = [self, Float, Fixnum, Bignum, Rational, Numeric, String] # , BigFloat
|
119
155
|
CLASSES_ACCEPTABLE.push BigFloat if defined? BigFloat
|
120
156
|
|
157
|
+
# Unary Operator: Plus
|
158
|
+
def +@
|
159
|
+
self
|
160
|
+
end
|
161
|
+
|
162
|
+
# Unary Operator: Minus
|
163
|
+
def -@
|
164
|
+
positive? ? NEGATIVE : POSITIVE
|
165
|
+
end
|
166
|
+
|
121
167
|
def infinity?
|
122
168
|
true
|
123
169
|
end
|
170
|
+
#alias_method :infinite?, :infinity? if !self.method_defined? :infinite? # Common with Float::INFINITY
|
171
|
+
## If the alias for :infinite? is defined as above, the following would raise
|
172
|
+
# NoMethodError: undefined method `>' for true:TrueClass
|
173
|
+
# in the operation
|
174
|
+
# Float::INFINITY <=> RangeExtd::Infinity::POSITIVE
|
175
|
+
#
|
124
176
|
|
125
177
|
def positive?
|
126
178
|
@positive
|
@@ -134,44 +186,53 @@ class RangeExtd < Range
|
|
134
186
|
|
135
187
|
# Always -1 or 1 except for itself and the corresponding infinities (== 0). See {#==}.
|
136
188
|
# Or, nil (as defined by Object), if the argument is not Comparable, such as, nil and IO.
|
189
|
+
#
|
137
190
|
# @return [Integer, nil]
|
138
191
|
def <=>(c)
|
139
|
-
if c.nil?
|
140
|
-
|
141
|
-
elsif
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
0
|
146
|
-
else
|
147
|
-
1
|
148
|
-
end
|
149
|
-
else # aka negative
|
150
|
-
if self == c
|
151
|
-
0
|
152
|
-
else
|
153
|
-
-1
|
154
|
-
end
|
192
|
+
if c.nil? || !c.class.method_defined?(:<=) # Not Comparable?
|
193
|
+
nil
|
194
|
+
elsif c == Float::INFINITY
|
195
|
+
nil # Special case.
|
196
|
+
else
|
197
|
+
(self == c) ? 0 : (@positive ? 1 : -1)
|
155
198
|
end
|
156
199
|
end
|
157
|
-
|
200
|
+
|
201
|
+
alias_method :greater_than_before_rangeextd_infinity?, :> if ! self.method_defined?(:greater_than_before_rangeextd_infinity?) # No overwriting.
|
202
|
+
# Special case for Float::INFINITY
|
203
|
+
#
|
204
|
+
# (Float::INFINITY > RangeExtd::Infinity::POSITIVE)
|
205
|
+
# raises ArgumentError and so does this method.
|
206
|
+
def >(c)
|
207
|
+
((c.abs rescue c) == Float::INFINITY) ? raise(ArgumentError, "RangeExtd::Infinity object not comparable with '#{__method__}' with Float::INFINITY") : greater_than_before_rangeextd_infinity?(c)
|
208
|
+
end
|
209
|
+
|
210
|
+
alias_method :less_than_before_rangeextd_infinity?, :< if ! self.method_defined?(:less_than_before_rangeextd_infinity?) # No overwriting.
|
211
|
+
# Special case for Float::INFINITY
|
212
|
+
#
|
213
|
+
# (Float::INFINITY > RangeExtd::Infinity::POSITIVE)
|
214
|
+
# raises ArgumentError and so does this method.
|
215
|
+
def <(c)
|
216
|
+
((c.abs rescue c) == Float::INFINITY) ? raise(ArgumentError, "RangeExtd::Infinity object not comparable with '#{__method__}' with Float::INFINITY") : less_than_before_rangeextd_infinity?(c)
|
217
|
+
end
|
218
|
+
|
158
219
|
# Always false except for itself and the corresponding {Float::INFINITY}
|
159
220
|
# and those that have methods of {#infinity?} and {#positive?}
|
160
221
|
# with the corresponding true/false values, in which case this returns true.
|
161
222
|
def ==(c)
|
162
223
|
if (Infinity === c)
|
163
224
|
(@positive ^! c.positive?) # It should be OK to compare object_id?
|
164
|
-
elsif c == FLOAT_INFINITY && @positive
|
165
|
-
|
166
|
-
elsif c == -FLOAT_INFINITY && !@positive
|
167
|
-
|
225
|
+
#elsif c == FLOAT_INFINITY && @positive
|
226
|
+
# true
|
227
|
+
#elsif c == -FLOAT_INFINITY && !@positive
|
228
|
+
# true
|
168
229
|
elsif defined?(c.infinity?) && defined?(c.positive?)
|
169
230
|
(c.infinity? && (@positive ^! c.positive?))
|
170
231
|
else
|
171
232
|
false
|
172
233
|
end
|
173
234
|
end
|
174
|
-
|
235
|
+
|
175
236
|
# Equivalent to {#==}
|
176
237
|
def ===(c)
|
177
238
|
self == c
|
@@ -283,6 +344,34 @@ __EOF__
|
|
283
344
|
end
|
284
345
|
end # def self.overwrite_compare(obj)
|
285
346
|
|
347
|
+
# True if obj is a kind of Infinity like this class
|
348
|
+
#
|
349
|
+
# This is similar to the following, but is in a duck-typing way:
|
350
|
+
#
|
351
|
+
# RangeExtd::Infinity === obj
|
352
|
+
#
|
353
|
+
# Note that this returns false for Float::INFINITY.
|
354
|
+
# If you want true for Float::INFINITY, use {RangeExtd::Infinity.infinite?} instead.
|
355
|
+
#
|
356
|
+
# @param obj [Object]
|
357
|
+
def self.infinity?(obj)
|
358
|
+
kl = obj.class
|
359
|
+
kl.method_defined?(:infinity?) && kl.method_defined?(:positive?) && kl.method_defined?(:negative?)
|
360
|
+
end
|
361
|
+
|
362
|
+
# True if obj is either Float::INFINITY or Infinity type.
|
363
|
+
#
|
364
|
+
# Note +Float#infinite?+ is defined - how to memorise this method name.
|
365
|
+
#
|
366
|
+
# @param obj [Object]
|
367
|
+
def self.infinite?(obj)
|
368
|
+
kl = obj.class
|
369
|
+
(kl.method_defined?(:infinite?) && obj.infinite?) || (kl.method_defined?(:infinity?) && obj.infinity?)
|
370
|
+
end
|
371
|
+
|
372
|
+
######################################
|
373
|
+
# Special tricky routine below. Do not rouch!
|
374
|
+
######################################
|
286
375
|
|
287
376
|
private
|
288
377
|
|
@@ -303,6 +392,10 @@ __EOF__
|
|
303
392
|
# Disable new() so no other object will be created.
|
304
393
|
private_class_method :new
|
305
394
|
|
395
|
+
######################################
|
396
|
+
# Special tricky routine below. Do not rouch!
|
397
|
+
######################################
|
398
|
+
|
306
399
|
warn_level = $VERBOSE
|
307
400
|
begin
|
308
401
|
$VERBOSE = nil # Suppress the warning in the following line.
|
@@ -350,43 +443,158 @@ class Object
|
|
350
443
|
# if c._is_what_i_expect?
|
351
444
|
# # Write your definition.
|
352
445
|
# else # When self does not know what to do with c.
|
353
|
-
# super
|
446
|
+
# super c # to call Object#<=>
|
354
447
|
# end
|
355
448
|
# end
|
356
449
|
# end
|
357
450
|
#
|
358
451
|
def <=>(c)
|
359
|
-
|
360
|
-
|
361
|
-
# NOTE: Duck-typing is inappropriate here.
|
362
|
-
# Only the objects that self wants to deal with here are
|
363
|
-
# the instances of RangeExtd::Infinity, and not other
|
364
|
-
# "infinity" object, such as, Float::INFINITY. So,
|
365
|
-
# (self <=> RangeExtd::Infinity::POSITIVE) # => -1
|
366
|
-
# (self <=> Float::INFINITY) # => nil
|
367
|
-
# in default.
|
368
|
-
if defined?(self.infinity?) && defined?(self.positive?)
|
369
|
-
if (self.positive? ^! c.positive?)
|
370
|
-
0
|
371
|
-
elsif self.positive?
|
372
|
-
1
|
373
|
-
else
|
374
|
-
-1
|
375
|
-
end
|
376
|
-
else
|
377
|
-
# (c <=> self) * (-1)
|
378
|
-
if c.positive?
|
379
|
-
-1
|
380
|
-
else
|
381
|
-
1
|
382
|
-
end
|
383
|
-
end
|
384
|
-
elsif object_id == c.object_id # (nil <=> nil) # => 0
|
385
|
-
0
|
386
|
-
else
|
387
|
-
nil
|
388
|
-
end # if defined?(self.<=) && RangeExtd::Infinity === c
|
452
|
+
return (-(c.send(__method__, self) || return)) if RangeExtd::Infinity.infinity? c
|
453
|
+
compare_obj_before_infinity(c)
|
389
454
|
end # def <=>(c)
|
390
455
|
end # class Object
|
391
456
|
|
392
457
|
|
458
|
+
#
|
459
|
+
# = class Numeric
|
460
|
+
#
|
461
|
+
# Modify {Numeric#>} and {Numeric#<} because +5 < RangeExtd::Infinity::POSITIVE+
|
462
|
+
# raises ArgumentError(!). In other words, +Integer#<+ does not respect
|
463
|
+
# +Object#<=>+ but rewrites it.
|
464
|
+
#
|
465
|
+
# I do not know if it has been always the case, or some changes have been made
|
466
|
+
# in more recent versions of Ruby.
|
467
|
+
#
|
468
|
+
# Note that +Float#<+ etc need to be redefined individually, because they seem
|
469
|
+
# not to use +Numeric#<+ any more.
|
470
|
+
class Numeric
|
471
|
+
|
472
|
+
alias_method :compare_than_numeric_before_infinity?, :<=> if ! self.method_defined?(:compare_than_numeric_before_infinity?) # No overwriting.
|
473
|
+
# Special case for comparison with a {RangeExtd::Infinity} instance.
|
474
|
+
def <=>(c)
|
475
|
+
# Default if the special case INFINITY.
|
476
|
+
return compare_than_numeric_before_infinity?(c) if ((abs rescue self) == Float::INFINITY)
|
477
|
+
|
478
|
+
return (-(c.send(__method__, self) || return)) if RangeExtd::Infinity.infinity? c
|
479
|
+
compare_than_numeric_before_infinity?(c)
|
480
|
+
end
|
481
|
+
|
482
|
+
alias_method :greater_than_numeric_before_infinity?, :> if ! self.method_defined?(:greater_than_numeric_before_infinity?) # No overwriting.
|
483
|
+
# Special case for comparison with a {RangeExtd::Infinity} instance.
|
484
|
+
def >(c)
|
485
|
+
# Default if self is Complex or something not Integer, Rational, Float or alike
|
486
|
+
# or the special case INFINITY.
|
487
|
+
return greater_than_numeric_before_infinity?(c) if !self.class.method_defined?(:>) || ((abs rescue self) == Float::INFINITY)
|
488
|
+
|
489
|
+
if RangeExtd::Infinity.infinity? c
|
490
|
+
c.negative?
|
491
|
+
else
|
492
|
+
greater_than_numeric_before_infinity?(c)
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
alias_method :less_than_numeric_before_infinity?, :< if ! self.method_defined?(:less_than_numeric_before_infinity?) # No overwriting.
|
497
|
+
# Special case for comparison with a {RangeExtd::Infinity} instance.
|
498
|
+
def <(c)
|
499
|
+
# Default if self is Complex or something not Integer, Rational, Float or alike
|
500
|
+
# or the special case INFINITY.
|
501
|
+
return less_than_numeric_before_infinity?(c) if !self.class.method_defined?(:>) || ((abs rescue self) == Float::INFINITY)
|
502
|
+
|
503
|
+
if RangeExtd::Infinity.infinity? c
|
504
|
+
c.positive?
|
505
|
+
else
|
506
|
+
less_than_numeric_before_infinity?(c)
|
507
|
+
end
|
508
|
+
end
|
509
|
+
end # class Numeric
|
510
|
+
|
511
|
+
|
512
|
+
#
|
513
|
+
# = class Float
|
514
|
+
#
|
515
|
+
# The same as {Numeric#>} and {Numeric#<}. See them for the background.
|
516
|
+
class Float
|
517
|
+
|
518
|
+
alias_method :compare_than_float_before_infinity?, :<=> if ! self.method_defined?(:compare_than_float_before_infinity?) # No overwriting.
|
519
|
+
# Special case for comparison with a {RangeExtd::Infinity} instance.
|
520
|
+
def <=>(c)
|
521
|
+
# Default if the special case INFINITY.
|
522
|
+
return compare_than_float_before_infinity?(c) if ((abs rescue self) == Float::INFINITY)
|
523
|
+
|
524
|
+
return (-(c.send(__method__, self) || return)) if RangeExtd::Infinity.infinity? c
|
525
|
+
compare_than_float_before_infinity?(c)
|
526
|
+
end
|
527
|
+
|
528
|
+
alias_method :greater_than_float_before_infinity?, :> if ! self.method_defined?(:greater_than_float_before_infinity?) # No overwriting.
|
529
|
+
# Special case for comparison with a {RangeExtd::Infinity} instance.
|
530
|
+
def >(c)
|
531
|
+
# Default if self is Complex or something not Integer, Rational, Float or alike
|
532
|
+
# or the special case INFINITY.
|
533
|
+
return greater_than_float_before_infinity?(c) if ((abs rescue self) == Float::INFINITY)
|
534
|
+
|
535
|
+
if RangeExtd::Infinity.infinity? c
|
536
|
+
c.negative?
|
537
|
+
else
|
538
|
+
greater_than_float_before_infinity?(c)
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
alias_method :less_than_float_before_infinity?, :< if ! self.method_defined?(:less_than_float_before_infinity?) # No overwriting.
|
543
|
+
# Special case for comparison with a {RangeExtd::Infinity} instance.
|
544
|
+
def <(c)
|
545
|
+
# Default if self is Complex or something not Integer, Rational, Float or alike
|
546
|
+
# or the special case INFINITY.
|
547
|
+
return less_than_float_before_infinity?(c) if ((abs rescue self) == Float::INFINITY)
|
548
|
+
|
549
|
+
if RangeExtd::Infinity.infinity? c
|
550
|
+
c.positive?
|
551
|
+
else
|
552
|
+
less_than_float_before_infinity?(c)
|
553
|
+
end
|
554
|
+
end
|
555
|
+
end # class Float
|
556
|
+
|
557
|
+
|
558
|
+
#
|
559
|
+
# = class Integer
|
560
|
+
#
|
561
|
+
# The same as {Numeric#>} and {Numeric#<}. See them for the background.
|
562
|
+
class Integer
|
563
|
+
|
564
|
+
alias_method :compare_than_integer_before_infinity?, :<=> if ! self.method_defined?(:compare_than_integer_before_infinity?) # No overwriting.
|
565
|
+
# Special case for comparison with a {RangeExtd::Infinity} instance.
|
566
|
+
def <=>(c)
|
567
|
+
# Default if the special case INFINITY (never happens in Default, but a user may define Integer::INFINITY).
|
568
|
+
return compare_than_integer_before_infinity?(c) if ((abs rescue self) == Float::INFINITY)
|
569
|
+
|
570
|
+
return (-(c.send(__method__, self) || return)) if RangeExtd::Infinity.infinity? c
|
571
|
+
compare_than_integer_before_infinity?(c)
|
572
|
+
end
|
573
|
+
|
574
|
+
alias_method :greater_than_integer_before_infinity?, :> if ! self.method_defined?(:greater_than_integer_before_infinity?) # No overwriting.
|
575
|
+
# Special case for comparison with a {RangeExtd::Infinity} instance.
|
576
|
+
def >(c)
|
577
|
+
# Default if self is not comparable (in case the Integer method is redifined by a user).
|
578
|
+
return greater_than_integer_before_infinity?(c) if !self.class.method_defined?(:>)
|
579
|
+
|
580
|
+
if RangeExtd::Infinity.infinity? c
|
581
|
+
c.negative?
|
582
|
+
else
|
583
|
+
greater_than_integer_before_infinity?(c)
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
alias_method :less_than_integer_before_infinity?, :< if ! self.method_defined?(:less_than_integer_before_infinity?) # No overwriting.
|
588
|
+
# Special case for comparison with a {RangeExtd::Infinity} instance.
|
589
|
+
def <(c)
|
590
|
+
# Default if self is not comparable (in case the Integer method is redifined by a user).
|
591
|
+
return less_than_integer_before_infinity?(c) if !self.class.method_defined?(:>)
|
592
|
+
|
593
|
+
if RangeExtd::Infinity.infinity? c
|
594
|
+
c.positive?
|
595
|
+
else
|
596
|
+
less_than_integer_before_infinity?(c)
|
597
|
+
end
|
598
|
+
end
|
599
|
+
end # class Integer
|
600
|
+
|
@@ -26,9 +26,6 @@ req_files.each do |req_file|
|
|
26
26
|
end
|
27
27
|
end # req_files.each do |req_file|
|
28
28
|
|
29
|
-
########################################
|
30
|
-
# Initial set up of 2 constants in RangeExtd.
|
31
|
-
########################################
|
32
29
|
|
33
30
|
# =Class RangeExtd
|
34
31
|
#
|
@@ -60,6 +57,10 @@ end # req_files.each do |req_file|
|
|
60
57
|
#
|
61
58
|
class RangeExtd < Range
|
62
59
|
|
60
|
+
# To conrol how the {RangeExtd} should be displayed or set (in one form).
|
61
|
+
# It can be read and reset by {RangeExtd.middle_strings} and
|
62
|
+
# {RangeExtd.middle_strings=}
|
63
|
+
# Default is +['', '', '<', '..', '.', '', '']+
|
63
64
|
@@middle_strings = []
|
64
65
|
|
65
66
|
# Error messages
|
@@ -726,6 +727,28 @@ class RangeExtd < Range
|
|
726
727
|
# in the range whereas 4.8 is not in the range by definition,
|
727
728
|
# but not the example right above.
|
728
729
|
#
|
730
|
+
# === Ruby 2.6 Endless Range and Infinity.
|
731
|
+
#
|
732
|
+
# Before RangeExtd Ver.1.1, if a {RangeExtd} object contains
|
733
|
+
# {RangeExtd::Infinity} objects for either begin or end, {#size} used to
|
734
|
+
# be always +Float::INFINITY+ no matter what the other object is
|
735
|
+
# (except when the other object is also a {RangeExtd::Infinity} object).
|
736
|
+
# However, since the introduction of the endless Range in Ruby 2.6,
|
737
|
+
# Ruby returns as follows:
|
738
|
+
#
|
739
|
+
# (5..).size # => Float::INFINITY
|
740
|
+
# (?a..).size # => nil
|
741
|
+
#
|
742
|
+
# Accordingly, this class {RangeExtd} now behaves the same as Ruby (2.6 or later).
|
743
|
+
#
|
744
|
+
# Similarly,
|
745
|
+
#
|
746
|
+
# (Float::INFINITY..Float::INFINITY).size
|
747
|
+
#
|
748
|
+
# has changed (I do not know in which Ruby version)!
|
749
|
+
# It used to be 0. However, As of Ruby 2.6, it is +FloatDomainError: NaN+
|
750
|
+
# Again this class now follows Ruby's default ({RangeExtd} Ver.1.0 or later).
|
751
|
+
#
|
729
752
|
# @note When both ends n are the same INFINITY (of the same parity),
|
730
753
|
# +(n..n).size+ used to be 0. As of Ruby 2.6, it is FloatDomainError: NaN.
|
731
754
|
# This routine follows what Ruby produces, depending on Ruby's version it is run on.
|
@@ -758,11 +781,16 @@ class RangeExtd < Range
|
|
758
781
|
# Note (Infinity..Infinity) => 0 (Range as in Ruby 2.1)
|
759
782
|
# however,
|
760
783
|
elsif (defined?(self.begin.infinity?) && self.begin.infinity? || self.begin == -Infinity::FLOAT_INFINITY) ||
|
761
|
-
(defined?(self.end.infinity?) && self.end.infinity? || self.end == Infinity::FLOAT_INFINITY)
|
784
|
+
(defined?(self.end.infinity?) && self.end.infinity? || self.end == Infinity::FLOAT_INFINITY) ||
|
785
|
+
(self.end.nil?) # RangeExtd#end can be nil only for Ruby-2.6
|
762
786
|
if self.begin == self.end
|
763
787
|
# This varies, depending on Ruby's version! It used to be 0. As of Ruby 2.6, it is FloatDomainError: NaN.
|
764
788
|
return (Float::INFINITY..Float::INFINITY).size
|
765
789
|
# return 0
|
790
|
+
elsif self.end.nil?
|
791
|
+
# Behaves as Ruby does -
|
792
|
+
# Infinity::FLOAT_INFINITY for Numeric and nil for any other
|
793
|
+
return (self.begin..nil).size
|
766
794
|
else
|
767
795
|
return Infinity::FLOAT_INFINITY
|
768
796
|
end
|
@@ -952,13 +980,40 @@ class RangeExtd < Range
|
|
952
980
|
if hsopt.has_key?(:exclude_end)
|
953
981
|
exclude_end = (hsopt[:exclude_end] && true)
|
954
982
|
end
|
955
|
-
# [RangeBeginValue, RangeEndValue, exclude_end?, exclude_begin?]
|
956
|
-
beginend + [exclude_end, exclude_begin]
|
957
983
|
|
984
|
+
# [RangeBeginValue, RangeEndValue, exclude_end?, exclude_begin?]
|
985
|
+
_normalize_infinity_float(beginend) + [exclude_end, exclude_begin]
|
958
986
|
end # def self._get_init_args(*inar)
|
959
|
-
|
960
987
|
private_class_method :_get_init_args # From Ruby 1.8.7 (?)
|
961
988
|
|
989
|
+
# Replaces {RangeExtd::Infinity} with {Float::INFINITY} when appropriate
|
990
|
+
#
|
991
|
+
# @param beginend [Array] 2-compoents
|
992
|
+
# @return [Array] 2-compoents
|
993
|
+
def self._normalize_infinity_float(beginend)
|
994
|
+
is_begin_inf = Infinity.infinity?(beginend[0])
|
995
|
+
return beginend if is_begin_inf ^! Infinity.infinity?(beginend[1])
|
996
|
+
|
997
|
+
# Now, only one of them is a {RangeExtd::Infinity} type object.
|
998
|
+
if is_begin_inf && beginend[1].class.method_defined?(:divmod)
|
999
|
+
[_normalize_infinity_float_core(beginend[0]), beginend[1]] # "begin" is Infinity
|
1000
|
+
elsif beginend[0].class.method_defined?(:divmod)
|
1001
|
+
[beginend[0], _normalize_infinity_float_core(beginend[1])] # "end" is Infinity
|
1002
|
+
else
|
1003
|
+
beginend
|
1004
|
+
end
|
1005
|
+
end
|
1006
|
+
private_class_method :_normalize_infinity_float # From Ruby 1.8.7 (?)
|
1007
|
+
|
1008
|
+
# @param inf [RangeExtd::Infinity]
|
1009
|
+
# @return [RangeExtd::Infinity, Float] +/-Float::INFINITY if Float
|
1010
|
+
def self._normalize_infinity_float_core(inf)
|
1011
|
+
msg = 'RangeExtd component of the RangeExtd::Infinity object replaced with Float::INFINITY.'
|
1012
|
+
warn msg if !$VERBOSE.nil?
|
1013
|
+
(inf.positive? ? 1 : -1) * Float::INFINITY
|
1014
|
+
end
|
1015
|
+
private_class_method :_normalize_infinity_float_core # From Ruby 1.8.7 (?)
|
1016
|
+
|
962
1017
|
|
963
1018
|
# Returns true if the range to be constructed (or given) is valid,
|
964
1019
|
# as a range, accepted in {RangeExtd}.
|
@@ -977,7 +1032,7 @@ class RangeExtd < Range
|
|
977
1032
|
# introduced in Ruby 2.6 (see below for the exceptions), both of which are valid.
|
978
1033
|
# For example, (nil..nil) is NOT valid (nb., it raised Exception in Ruby 1.8).
|
979
1034
|
# 2. Except for {RangeExtd::NONE}, {#begin} must have the method +<=+.
|
980
|
-
# Therefore, some Endless Ranges (Ruby 2.6 and
|
1035
|
+
# Therefore, some Endless Ranges (Ruby 2.6 and later) like (true..) are *not* valid.
|
981
1036
|
# Note even "true" has the method +<=>+ and hence checking +<=+ is essential.
|
982
1037
|
# 3. {#begin} must be smaller than or equal to {#end},
|
983
1038
|
# that is, ({#begin} <=> {#end}) must be either -1 or 0.
|
@@ -1053,7 +1108,7 @@ class RangeExtd < Range
|
|
1053
1108
|
rescue NoMethodError, TypeError
|
1054
1109
|
if (Float === vend && defined?(vbeg.infinity?) && vbeg.infinity?) ||
|
1055
1110
|
(Float === vbeg && defined?(vend.infinity?) && vend.infinity?)
|
1056
|
-
warn self.const_get(:ERR_MSGS)[:infinity_compare] # one of the tests comes here.
|
1111
|
+
warn self.const_get(:ERR_MSGS)[:infinity_compare] if !$VERBOSE.nil? # one of the tests comes here.
|
1057
1112
|
end
|
1058
1113
|
return false # return
|
1059
1114
|
end
|
@@ -1074,7 +1129,7 @@ class RangeExtd < Range
|
|
1074
1129
|
else
|
1075
1130
|
if (Float === vend && defined?(vbeg.infinity?) && vbeg.infinity?) ||
|
1076
1131
|
(Float === vbeg && defined?(vend.infinity?) && vend.infinity?)
|
1077
|
-
warn self.const_get(:ERR_MSGS)[:infinity_compare] # not tested so far?
|
1132
|
+
warn self.const_get(:ERR_MSGS)[:infinity_compare] if !$VERBOSE.nil? # not tested so far?
|
1078
1133
|
end
|
1079
1134
|
false # Not Comparable.
|
1080
1135
|
end # case t
|
@@ -1082,7 +1137,6 @@ class RangeExtd < Range
|
|
1082
1137
|
end
|
1083
1138
|
end # def valid?
|
1084
1139
|
|
1085
|
-
|
1086
1140
|
# Set the class variable to be used in {RangeExtd#to_s} and {RangeExtd#inspect}
|
1087
1141
|
# to configure the format of their returned values.
|
1088
1142
|
#
|
@@ -1283,11 +1337,11 @@ class RangeExtd < Range
|
|
1283
1337
|
# No range.
|
1284
1338
|
# In Ruby1.8, this causes ArgumentError: bad value for range (because (nil..nil) is unaccepted).
|
1285
1339
|
NONE = RangeExtd.new(nil, nil, true, true, :Constant)
|
1286
|
-
#NONE
|
1340
|
+
#NONE= RangeExtd.new(nil...nil, true, true, :Constant)
|
1287
1341
|
|
1288
1342
|
# Range covers everything.
|
1289
1343
|
ALL = RangeExtd.new(Infinity::NEGATIVE, Infinity::POSITIVE, false, false, :Constant)
|
1290
|
-
#ALL
|
1344
|
+
#ALL = RangeExtd.new(Infinity::NEGATIVE..Infinity::POSITIVE, false, false, :Constant)
|
1291
1345
|
|
1292
1346
|
end # class RangeExtd < Range
|
1293
1347
|
|
data/test/test_range_extd.rb
CHANGED
@@ -49,6 +49,12 @@ end
|
|
49
49
|
# Unit Test
|
50
50
|
#################################################
|
51
51
|
|
52
|
+
begin
|
53
|
+
_ = Rational(2, 3)
|
54
|
+
rescue
|
55
|
+
require 'rational'
|
56
|
+
end
|
57
|
+
|
52
58
|
#if $0 == __FILE__
|
53
59
|
gem "minitest"
|
54
60
|
# require 'minitest/unit'
|
@@ -142,6 +148,10 @@ gem "minitest"
|
|
142
148
|
class TestUnitFoo < MiniTest::Unit::TestCase
|
143
149
|
T = true
|
144
150
|
F = false
|
151
|
+
InfF = Float::INFINITY
|
152
|
+
InfP = RangeExtd::Infinity::POSITIVE
|
153
|
+
InfN = RangeExtd::Infinity::NEGATIVE
|
154
|
+
|
145
155
|
def setup
|
146
156
|
@ib = 1
|
147
157
|
@ie = 6
|
@@ -166,6 +176,48 @@ gem "minitest"
|
|
166
176
|
assert_equal 0, (IO <=> IO)
|
167
177
|
end # def test_object_compare
|
168
178
|
|
179
|
+
# InfP (RangeExtd::Infinity::POSITIVE) and InfN (RangeExtd::Infinity::NEGATIVE)
|
180
|
+
# are always comparable with any comparable objects except for
|
181
|
+
# Float::INFINITY, in which case ArgumentError is raised.
|
182
|
+
def test_infinity_compare
|
183
|
+
assert_operator 7.7, '<', InfF
|
184
|
+
assert_operator 7.7, '<', InfP
|
185
|
+
assert_operator 7.7, '>', InfN
|
186
|
+
assert_operator InfP, '>', 7.7
|
187
|
+
assert_operator InfN, '<', 7.7
|
188
|
+
assert_operator 8, '<', InfF
|
189
|
+
assert_operator 8, '<', InfP
|
190
|
+
assert_operator Rational(2, 3), '<', InfF
|
191
|
+
assert_operator Rational(2, 3), '<', InfP
|
192
|
+
assert_operator InfP, '>', Rational(2, 3)
|
193
|
+
assert_operator InfN, '<', Rational(2, 3)
|
194
|
+
assert_operator 'h', '<', InfP
|
195
|
+
assert_operator 'h', '>', InfN
|
196
|
+
assert_raises(ArgumentError) { InfF < InfP }
|
197
|
+
assert_raises(ArgumentError) { InfP < InfF }
|
198
|
+
assert_raises(ArgumentError) { InfP < -InfF }
|
199
|
+
assert_raises(ArgumentError) { InfP > InfF }
|
200
|
+
assert_raises(ArgumentError) { InfP > -InfF }
|
201
|
+
assert_raises(ArgumentError) { InfN < InfF }
|
202
|
+
assert_raises(ArgumentError) { InfN < -InfF }
|
203
|
+
assert_raises(ArgumentError) { InfF < Object.new }
|
204
|
+
assert_raises(ArgumentError) { InfP < Object.new }
|
205
|
+
assert_nil (InfF <=> InfP)
|
206
|
+
assert_nil (InfP <=> InfF)
|
207
|
+
assert_equal(-1, 7.7 <=> InfP)
|
208
|
+
assert_equal( 1, 7.7 <=> InfN)
|
209
|
+
assert_equal( 1, InfP <=> 7.7)
|
210
|
+
assert_equal(-1, InfN <=> 7.7)
|
211
|
+
assert_equal(-1, 5 <=> InfP)
|
212
|
+
assert_equal( 1, 5 <=> InfN)
|
213
|
+
assert_equal( 1, InfP <=> 5)
|
214
|
+
assert_equal(-1, InfN <=> 5)
|
215
|
+
assert_equal(-1, 'h' <=> InfP)
|
216
|
+
assert_equal(-1, InfN <=> 'h')
|
217
|
+
#assert_raises(ArgumentError) { puts "########## #{(InfP > InfF).inspect}";InfP < InfF }
|
218
|
+
#puts "########## #{(InfP <=> InfF).inspect}"
|
219
|
+
end
|
220
|
+
|
169
221
|
def test_overwrite_compare
|
170
222
|
assert_nil (Float::INFINITY <=> RangeExtd::Infinity::POSITIVE)
|
171
223
|
assert_nil RangeExtd::Infinity.overwrite_compare(Numeric)
|
@@ -295,6 +347,15 @@ gem "minitest"
|
|
295
347
|
end
|
296
348
|
|
297
349
|
def test_new_endless_range01
|
350
|
+
begin
|
351
|
+
_ = (0..nil)
|
352
|
+
rescue ArgumentError
|
353
|
+
# Before Ruby 2.6
|
354
|
+
assert_raises(ArgumentError) {RangeExtd.new(-2, nil)}
|
355
|
+
return # Before Ruby 2.6
|
356
|
+
end
|
357
|
+
|
358
|
+
# Ruby 2.6 upwards
|
298
359
|
ra00 = (-2..)
|
299
360
|
rae0 = RangeExtd.new(ra00)
|
300
361
|
assert rae0.valid?
|
@@ -303,9 +364,26 @@ gem "minitest"
|
|
303
364
|
assert_equal Float::INFINITY, rae0.size
|
304
365
|
assert_equal ra00.exclude_end?, rae0.exclude_end?
|
305
366
|
refute rae0.exclude_begin?
|
367
|
+
|
368
|
+
rae0 = RangeExtd.new(-2, nil)
|
369
|
+
assert rae0.valid?
|
370
|
+
assert_equal(-2, rae0.begin)
|
371
|
+
assert_nil rae0.end
|
372
|
+
assert_equal Float::INFINITY, rae0.size
|
373
|
+
assert_equal ra00.exclude_end?, rae0.exclude_end?
|
374
|
+
refute rae0.exclude_begin?
|
306
375
|
end
|
307
376
|
|
308
377
|
def test_new_endless_range02
|
378
|
+
begin
|
379
|
+
_ = (?d...nil)
|
380
|
+
rescue ArgumentError
|
381
|
+
# Before Ruby 2.6
|
382
|
+
assert_raises(ArgumentError) {RangeExtd.new(?d, nil)}
|
383
|
+
return # Before Ruby 2.6
|
384
|
+
end
|
385
|
+
|
386
|
+
# Ruby 2.6 upwards
|
309
387
|
ra00 = (Float::INFINITY...)
|
310
388
|
rae0 = RangeExtd.new(ra00)
|
311
389
|
assert rae0.valid?
|
@@ -314,6 +392,38 @@ gem "minitest"
|
|
314
392
|
assert_equal Float::INFINITY, rae0.size
|
315
393
|
assert_equal ra00.exclude_end?, rae0.exclude_end?
|
316
394
|
refute rae0.exclude_begin?
|
395
|
+
|
396
|
+
assert_equal Float::INFINITY, RangeExtd.new(?d, RangeExtd::Infinity::POSITIVE).size
|
397
|
+
assert_equal Float::INFINITY, RangeExtd.new(RangeExtd::Infinity::NEGATIVE, ?d).size
|
398
|
+
|
399
|
+
rae0 = RangeExtd.new(?d, nil, false, true)
|
400
|
+
assert rae0.valid?
|
401
|
+
assert_equal(?d, rae0.begin)
|
402
|
+
assert_nil rae0.end
|
403
|
+
# assert_equal (?d..nil).size, rae0.size # assert_nil warning!
|
404
|
+
assert_nil (?d..nil).size
|
405
|
+
assert_nil rae0.size
|
406
|
+
assert_equal true, rae0.exclude_end?
|
407
|
+
refute rae0.exclude_begin?
|
408
|
+
end
|
409
|
+
|
410
|
+
def test_new_endless_range03
|
411
|
+
begin
|
412
|
+
_ = (?d...nil)
|
413
|
+
rescue ArgumentError
|
414
|
+
# Before Ruby 2.6
|
415
|
+
assert_raises(ArgumentError) {RangeExtd.new(?d, nil)}
|
416
|
+
return # Before Ruby 2.6
|
417
|
+
end
|
418
|
+
|
419
|
+
ra00 = (-Float::INFINITY...)
|
420
|
+
rae0 = RangeExtd.new(ra00)
|
421
|
+
assert rae0.valid?
|
422
|
+
assert_equal(-Float::INFINITY, rae0.begin)
|
423
|
+
assert_nil rae0.end
|
424
|
+
assert_equal Float::INFINITY, rae0.size
|
425
|
+
assert_equal ra00.exclude_end?, rae0.exclude_end?
|
426
|
+
refute rae0.exclude_begin?
|
317
427
|
end
|
318
428
|
|
319
429
|
def test_new_middle_strings
|
@@ -419,19 +529,26 @@ gem "minitest"
|
|
419
529
|
assert_equal RangeExtd::NONE, RaE(?a, ?a, true, true)
|
420
530
|
assert_equal (0..0), RaE(0, 0, false, false)
|
421
531
|
|
532
|
+
# The following used to raise RangeError (Ver.0.4 and 1.0) or ArgumentError (<= Ver.0.4.0)
|
533
|
+
assert_output('', /Infinity/i){RaE(RangeExtd::Infinity::NEGATIVE, Float::INFINITY)} # Warning = "RangeExtd component of the RangeExtd::Infinity object replaced with Float::INFINITY"
|
534
|
+
capture_io{
|
535
|
+
ra_b = RaE(InfN, InfF).begin # RangeExtd::Infinity::NEGATIVE replaced with -Float::INFINITY
|
536
|
+
assert_equal -InfF, ra_b
|
537
|
+
assert_operator Float, '===', ra_b
|
538
|
+
}
|
539
|
+
|
422
540
|
# Wrong range (Infinity input)
|
423
541
|
assert_raises(re){ RaE(?a, RangeExtd::Infinity::NEGATIVE) }
|
424
542
|
assert_equal (RangeExtd::Infinity::NEGATIVE..?a), RaE(RangeExtd::Infinity::NEGATIVE, ?a)
|
425
543
|
assert_equal (RangeExtd::Infinity::NEGATIVE...?a), RaE(RangeExtd::Infinity::NEGATIVE, ?a, nil, 3)
|
426
544
|
assert_equal (?a..RangeExtd::Infinity::POSITIVE), RaE(?a, RangeExtd::Infinity::POSITIVE)
|
427
545
|
assert_equal RangeExtd, RaE(?a, RangeExtd::Infinity::POSITIVE, 1).class
|
428
|
-
|
429
|
-
assert_raises(re){ RaE(-Float::INFINITY, RangeExtd::Infinity::POSITIVE) } # Float::INFINITY is an exception - you should not mix it up.
|
546
|
+
|
430
547
|
assert_raises(re){ RaE(RangeExtd::Infinity::POSITIVE, ?a) }
|
431
548
|
assert_raises(re){ RaE(RangeExtd::Infinity::POSITIVE, RangeExtd::Infinity::NEGATIVE) }
|
432
549
|
assert_equal RangeExtd, RaE(RangeExtd::Infinity::NEGATIVE, RangeExtd::Infinity::POSITIVE).class
|
433
|
-
assert_raises(re){ RaE(RangeExtd::Infinity::NEGATIVE, 0, false, false) } # For Numeric, you should use -Float::INFINITY
|
434
|
-
assert_raises(re){ RaE(0, RangeExtd::Infinity::POSITIVE, false, false) } # For Numeric, you should use Float::INFINITY
|
550
|
+
# assert_raises(re){ RaE(RangeExtd::Infinity::NEGATIVE, 0, false, false) } # For Numeric, you should use -Float::INFINITY
|
551
|
+
# assert_raises(re){ RaE(0, RangeExtd::Infinity::POSITIVE, false, false) } # For Numeric, you should use Float::INFINITY
|
435
552
|
assert_equal RangeExtd, RaE(RangeExtd::Infinity::NEGATIVE, ?a, false, false).class
|
436
553
|
assert_equal RangeExtd, RaE(?a, RangeExtd::Infinity::POSITIVE, false, false).class
|
437
554
|
# assert_raises(ae){ RaE(RangeExtd::Infinity::NEGATIVE, ?a, true) } #### No exception. Is it OK???
|
@@ -1051,12 +1168,20 @@ gem "minitest"
|
|
1051
1168
|
assert_equal RangeExtd::Infinity::NEGATIVE, RangeExtd::Infinity::NEGATIVE
|
1052
1169
|
assert_equal RangeExtd::Infinity::POSITIVE, RangeExtd::Infinity::POSITIVE.succ
|
1053
1170
|
assert_equal RangeExtd::Infinity::NEGATIVE, RangeExtd::Infinity::NEGATIVE.succ
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1171
|
+
refute_equal(-Float::INFINITY, RangeExtd::Infinity::NEGATIVE)
|
1172
|
+
refute_equal Float::INFINITY, RangeExtd::Infinity::POSITIVE
|
1173
|
+
assert_raises(ArgumentError) { Float::INFINITY < RangeExtd::Infinity::POSITIVE }
|
1174
|
+
assert_raises(ArgumentError) { Float::INFINITY > RangeExtd::Infinity::POSITIVE }
|
1175
|
+
assert_raises(ArgumentError) { Float::INFINITY > RangeExtd::Infinity::NEGATIVE }
|
1176
|
+
assert_raises(ArgumentError) { RangeExtd::Infinity::NEGATIVE > -Float::INFINITY }
|
1177
|
+
assert_raises(ArgumentError) { RangeExtd::Infinity::NEGATIVE > Float::INFINITY }
|
1178
|
+
assert_raises(ArgumentError) { RangeExtd::Infinity::NEGATIVE < -Float::INFINITY }
|
1179
|
+
assert_raises(ArgumentError) { RangeExtd::Infinity::POSITIVE > Float::INFINITY }
|
1180
|
+
assert_raises(ArgumentError) { RangeExtd::Infinity::POSITIVE < -Float::INFINITY }
|
1181
|
+
#assert !(RangeExtd::Infinity::POSITIVE > Float::INFINITY) # Before Ver.1.1
|
1182
|
+
#assert !(RangeExtd::Infinity::NEGATIVE > -Float::INFINITY) # Before Ver.1.1
|
1183
|
+
#assert !(RangeExtd::Infinity::POSITIVE > Float::INFINITY) # Before Ver.1.1
|
1184
|
+
#assert !(RangeExtd::Infinity::POSITIVE < Float::INFINITY) # Before Ver.1.1
|
1060
1185
|
assert (RangeExtd::Infinity::POSITIVE > 0)
|
1061
1186
|
assert (RangeExtd::Infinity::POSITIVE > RangeExtd::Infinity::NEGATIVE)
|
1062
1187
|
assert (RangeExtd::Infinity::NEGATIVE < 0)
|
@@ -1068,6 +1193,8 @@ gem "minitest"
|
|
1068
1193
|
assert !(RangeExtd::Infinity::POSITIVE === RangeExtd::Infinity::NEGATIVE)
|
1069
1194
|
assert !(RangeExtd::Infinity::NEGATIVE === RangeExtd::Infinity::POSITIVE)
|
1070
1195
|
|
1196
|
+
#### Comment valid up to Ver.1.0 (changed in Ver.1.1)
|
1197
|
+
#
|
1071
1198
|
## This is the case so far. Rewrite Float/Fixnum/Bignum/Rational??
|
1072
1199
|
## It would get slow, though! It is a lot better to use Float::INFINITY, instead.
|
1073
1200
|
# assert_raises ArgumentError do
|
@@ -1082,6 +1209,21 @@ gem "minitest"
|
|
1082
1209
|
assert_equal(-1, (Time.now <=> RangeExtd::Infinity::POSITIVE))
|
1083
1210
|
end
|
1084
1211
|
|
1212
|
+
def test_is_infinities
|
1213
|
+
# infinity?
|
1214
|
+
refute RangeExtd::Infinity.infinity? 5
|
1215
|
+
refute RangeExtd::Infinity.infinity? InfF
|
1216
|
+
assert RangeExtd::Infinity.infinity? InfP
|
1217
|
+
assert RangeExtd::Infinity.infinity? InfN
|
1218
|
+
assert RangeExtd::Infinity.infinity? RangeExtd::ALL.begin
|
1219
|
+
|
1220
|
+
# infinite? (similar but different!)
|
1221
|
+
refute RangeExtd::Infinity.infinite? 5
|
1222
|
+
assert RangeExtd::Infinity.infinite? InfF
|
1223
|
+
assert RangeExtd::Infinity.infinite? InfP
|
1224
|
+
assert RangeExtd::Infinity.infinite? InfN
|
1225
|
+
assert RangeExtd::Infinity.infinite? RangeExtd::ALL.begin
|
1226
|
+
end
|
1085
1227
|
|
1086
1228
|
def test_RangeExtdClass_valid
|
1087
1229
|
assert !RangeExtd.valid?(nil, nil, 9,9) # All 3 were true up to Version 0.1.0
|
@@ -1303,8 +1445,8 @@ gem "minitest"
|
|
1303
1445
|
assert RangeExtd::ALL.valid?
|
1304
1446
|
assert !RangeExtd::ALL.null?
|
1305
1447
|
assert !RangeExtd::ALL.empty?
|
1306
|
-
|
1307
|
-
|
1448
|
+
refute_equal (-Float::INFINITY..Float::INFINITY), RangeExtd::ALL
|
1449
|
+
refute_equal RangeExtd::ALL, (-Float::INFINITY..Float::INFINITY)
|
1308
1450
|
assert_equal RangeExtd::Infinity::POSITIVE, RangeExtd::ALL.end
|
1309
1451
|
assert_equal RangeExtd::Infinity::NEGATIVE, RangeExtd::ALL.begin
|
1310
1452
|
end
|
@@ -1377,7 +1519,7 @@ gem "minitest"
|
|
1377
1519
|
assert rs.cover?(?x)
|
1378
1520
|
assert_nil (rs === ?x)
|
1379
1521
|
assert_equal RangeExtd::Infinity::NEGATIVE, rs.begin # It is Infinity,
|
1380
|
-
|
1522
|
+
refute_equal(-Float::INFINITY, rs.begin)
|
1381
1523
|
assert ! rs.begin.positive?
|
1382
1524
|
assert_equal Float::INFINITY, rs.size
|
1383
1525
|
assert_raises TypeError do
|
@@ -1385,6 +1527,12 @@ gem "minitest"
|
|
1385
1527
|
end
|
1386
1528
|
end
|
1387
1529
|
|
1530
|
+
def test_infinity_unary_operators
|
1531
|
+
assert_equal RangeExtd::Infinity::POSITIVE, +RangeExtd::Infinity::POSITIVE
|
1532
|
+
assert_equal RangeExtd::Infinity::NEGATIVE, -RangeExtd::Infinity::POSITIVE
|
1533
|
+
assert_equal RangeExtd::Infinity::NEGATIVE, +RangeExtd::Infinity::NEGATIVE
|
1534
|
+
assert_equal RangeExtd::Infinity::POSITIVE, -RangeExtd::Infinity::NEGATIVE
|
1535
|
+
end
|
1388
1536
|
|
1389
1537
|
# Tests of all the examples in the document.
|
1390
1538
|
def test_in_document
|
@@ -1579,7 +1727,7 @@ gem "minitest"
|
|
1579
1727
|
# class Infinity
|
1580
1728
|
assert_equal( -1, (?z <=> RangeExtd::Infinity::POSITIVE))
|
1581
1729
|
assert_equal 1, (RangeExtd::Infinity::POSITIVE <=> ?z)
|
1582
|
-
|
1730
|
+
assert_equal( -1, (50 <=> RangeExtd::Infinity::POSITIVE))
|
1583
1731
|
assert_equal 1, (RangeExtd::Infinity::POSITIVE <=> 50)
|
1584
1732
|
end # def test_in_document
|
1585
1733
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: range_extd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.1'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masa Sakano
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Package for a subclass of Range, RangeExtd and RangeExtd::Infinity. The
|
14
14
|
former defines a range that enables an exclusion of the begin boundary, in addition
|