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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32649fb2085566146ed0bd20a5f1198f4030f56477ea64cb4f7822ce6288ff24
4
- data.tar.gz: 3fe7fb3ee23f9cd41550445e1482f86292b84dad8b13f0a3984b5e077a16a740
3
+ metadata.gz: 2ef735cf8d777f8f86ab2a5d3654577f06f0b41abf796c5c7147bc23482741dc
4
+ data.tar.gz: 33cf0bf6894c7de27b3c2714c03ba3042235751bd2bbeb506c0105c66badd110
5
5
  SHA512:
6
- metadata.gz: bc7050082f5af7734ee5946c1f51d21ed633ed275ef93ed9adf9844c8a965f9acab24eef8658cdb06891b852b05ab27bd8a81d0904bce15fbb9a0b0dfb0ba7e1
7
- data.tar.gz: 4bf22fb1d18614b5afed4bb8bed88bea3aeb0f90fa8da4c3345be3ee58561313b28453244910c7bac306592945768208dc03cb866c67201eea6c13bc4dbedc34
6
+ metadata.gz: 2240719d2e3f7f7933cea2e6b03268b87f0357526851b8a54b1645a320b35a44027808063df2176bbe4ac51ffacc91d517c5999c9c382244ab99a29219bbf795
7
+ data.tar.gz: 32f5f4b3cc81aee0bb099a33a6c905e713896eb875dc749cbb6365243f3f81eebfaf75604031a328faa31bbdcc8466956182cef03fe12d4b5d4d2f6fb59db810
data/ChangeLog CHANGED
@@ -1,16 +1,16 @@
1
1
  -----
2
- (Version: 1.0)
3
- 2019-10-30 Masa Sakano
4
- * Release of Ver.1.0.
5
- * Endless Range introduced in Ruby 2.6 is now fully supported.
6
- * RangeError is raised now when it is appropriate in initialisation, where ArgumentError used to be raised.
7
-
8
- -----
9
- (Version: 1.0)
10
- 2019-10-30 Masa Sakano
11
- * Release of Ver.1.0.
12
- * Endless Range introduced in Ruby 2.6 is now fully supported.
13
- * RangeError is raised now when it is appropriate in initialisation, where ArgumentError used to be raised.
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
@@ -1,3 +1,7 @@
1
+ -----
2
+ (Version: 1.1) 2019-11-01
3
+ * Release of Ver.1.1. A significant upgrade with some change in the specification of how to deal with infinities.
4
+
1
5
  -----
2
6
  (Version: 1.0) 2019-10-30
3
7
  * Release of Ver.1.0. Supports Endless Range in Ruby 2.6.
@@ -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.0 finally!
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 Rangeary.
87
- https://rubygems.org/gems/rangeary
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
- **Note** +RangeExtd::Infinity::POSITIVE+ is practically the same as
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 < imagine a_t sakano dot co dot uk >
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 < imagine a_t sakano dot co dot uk >
767
+ 著者:: Masa Sakano < info a_t wisebabel dot com >
737
768
  利用許諾条項:: MIT.
738
769
  保証:: 一切無し。
739
770
  バージョン:: Semantic Versioning (2.0.0) http://semver.org/
@@ -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.0 finally!
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 Rangeary.
87
- https://rubygems.org/gems/rangeary
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 class.
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
- # Note that the unary operand [#-@] is not defined.
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
- super
141
- elsif !defined?(c.<=) # Not Comparable?
142
- super
143
- elsif @positive
144
- if self == c
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
- true
166
- elsif c == -FLOAT_INFINITY && !@positive
167
- true
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 # to call Object#<=>
446
+ # super c # to call Object#<=>
354
447
  # end
355
448
  # end
356
449
  # end
357
450
  #
358
451
  def <=>(c)
359
- if defined?(self.<=) && RangeExtd::Infinity === c
360
- # if defined?(self.<=) && defined?(c.infinity?) && defined?(c.positive?)
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 upwards) like (true..) are *not* valid.
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 = RangeExtd.new(nil...nil, true, true, :Constant)
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 = RangeExtd.new(Infinity::NEGATIVE..Infinity::POSITIVE, false, false, :Constant)
1344
+ #ALL = RangeExtd.new(Infinity::NEGATIVE..Infinity::POSITIVE, false, false, :Constant)
1291
1345
 
1292
1346
  end # class RangeExtd < Range
1293
1347
 
@@ -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
- assert_raises(re){ RaE(RangeExtd::Infinity::NEGATIVE, Float::INFINITY) } # Float::INFINITY is an exception - you should not mix it up.
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
- assert_equal(-Float::INFINITY, RangeExtd::Infinity::NEGATIVE)
1055
- assert_equal Float::INFINITY, RangeExtd::Infinity::POSITIVE
1056
- assert !(RangeExtd::Infinity::NEGATIVE > -Float::INFINITY)
1057
- assert !(RangeExtd::Infinity::NEGATIVE < -Float::INFINITY)
1058
- assert !(RangeExtd::Infinity::POSITIVE > Float::INFINITY)
1059
- assert !(RangeExtd::Infinity::POSITIVE < Float::INFINITY)
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
- assert_equal (-Float::INFINITY..Float::INFINITY), RangeExtd::ALL
1307
- assert_equal RangeExtd::ALL, (-Float::INFINITY..Float::INFINITY)
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
- assert_equal(-Float::INFINITY, rs.begin) # but still equal to Float.
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
- assert_nil (50 <=> RangeExtd::Infinity::POSITIVE)
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.0'
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-10-30 00:00:00.000000000 Z
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