rangesmaller 1.0.0 → 1.0.2
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/README.rdoc +9 -2
- data/lib/rangesmaller/rangesmaller.rb +66 -50
- data/rangesmaller.gemspec +1 -1
- data/test/test_rangesmaller.rb +6 -2
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2f34ade6a7332bb19809904e8b89b419c5c71c1
|
4
|
+
data.tar.gz: 2931d7e5c7e98cedffab98faf3dfb45f83e638dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48ee7f0ef72c8cf5db14554f2843b69fa3d06728c5eede5092bbd8b9c2b0a5516922d8131d0a3442c1e55c92af997d001860d2085876c47cd3b6c81fdb7b0947
|
7
|
+
data.tar.gz: 7990cd5e77b37a10d1be51a069e97c36eabf56834fb9725764c542e3b302882b2d81a57e08f2956e99e0c38f62e7481102fcf506e30b098a73ca890d45b74df3
|
data/README.rdoc
CHANGED
@@ -21,7 +21,10 @@ A file
|
|
21
21
|
rangesmaller/rangesmaller.rb
|
22
22
|
should be installed in one of your $LOAD_PATH
|
23
23
|
|
24
|
-
|
24
|
+
Alternatively get it from
|
25
|
+
http://rubygems.org/gems/rangesmaller
|
26
|
+
|
27
|
+
Then all you need to do is
|
25
28
|
require 'rangesmaller'
|
26
29
|
in your Ruby script (or irb).
|
27
30
|
|
@@ -82,10 +85,14 @@ They are evaluated as follows:
|
|
82
85
|
* No thorough test for Ruby 1.8 or earlier has been done, although there is no known fault.
|
83
86
|
|
84
87
|
|
88
|
+
== ToDo
|
89
|
+
|
90
|
+
Nothing planned.
|
91
|
+
|
85
92
|
== Copyright etc
|
86
93
|
|
87
94
|
Author:: Masa Sakano < imagine a_t sakano dot co dot uk >
|
88
|
-
License::
|
95
|
+
License:: MIT.
|
89
96
|
Warranty:: No warranty whatsoever.
|
90
97
|
|
91
98
|
|
@@ -25,23 +25,23 @@ class Rangesmaller < Range
|
|
25
25
|
# @param [Rangesmaller] key describe key param
|
26
26
|
#
|
27
27
|
# @overload new(range, opts)
|
28
|
-
# @param [Range] standard Range object
|
29
|
-
# @option opts [Object] :exclude_begin the begin boundary is excluded, if false (Default)
|
28
|
+
# @param range range [Range] standard Range object
|
29
|
+
# @option opts opts [Object] :exclude_begin the begin boundary is excluded, if false (Default)
|
30
30
|
#
|
31
|
-
# @overload new(
|
31
|
+
# @overload new(obj_begin, obj_end, exclude_end=false)
|
32
32
|
# This form is not recomended, but for the sake of compatibility with Range.
|
33
|
-
# @param [Object] Any object (preferably {
|
34
|
-
# @param [Object] Any object, compatible with begin
|
35
|
-
# @param [Object] true or false(Default) or any.
|
33
|
+
# @param obj_begin [Object] Any object (preferably {Comparable})
|
34
|
+
# @param obj_end [Object] Any object, compatible with begin
|
35
|
+
# @param exclude_end [Object] true or false(Default) or any.
|
36
36
|
#
|
37
|
-
# @overload new(
|
38
|
-
# @param [Object] Any object (preferably {#Comparable})
|
39
|
-
# @param [Object] Any object, compatible with begin
|
40
|
-
# @param [Hash] see below
|
37
|
+
# @overload new(obj_begin, obj_end, opts)
|
38
|
+
# @param obj_begin [Object] Any object (preferably {#Comparable})
|
39
|
+
# @param obj_end [Object] Any object, compatible with begin
|
40
|
+
# @param opts [Hash] see below
|
41
41
|
# @option opts [Object] :exclude_end the end boundary is excluded, if false (Default)
|
42
42
|
# @option opts [Object] :exclude_begin the begin boundary is excluded, if false (Default)
|
43
43
|
#
|
44
|
-
# @note The
|
44
|
+
# @note The here-mentioned "any" object means any object that can consist of {Range}.
|
45
45
|
# For example, (nil..nil) is accepted, but (Complex(2,3)..Complex(2,3)) is not.
|
46
46
|
#
|
47
47
|
def initialize(*inar)
|
@@ -90,7 +90,7 @@ class Rangesmaller < Range
|
|
90
90
|
@rangepart = r
|
91
91
|
begin
|
92
92
|
if inar[1].has_key?(:exclude_end)
|
93
|
-
if inar[1][:exclude_end]
|
93
|
+
if inar[1][:exclude_end] ^ r.exclude_end?
|
94
94
|
warn "Warning(Rangesmaller.new): Option :exclude_end is given, but is meaningless, as Range is also given."
|
95
95
|
end
|
96
96
|
end
|
@@ -139,21 +139,20 @@ class Rangesmaller < Range
|
|
139
139
|
|
140
140
|
|
141
141
|
# Returns false if the "begin" boundary is excluded, or true otherwise.
|
142
|
-
# @return [TrueClass]
|
143
|
-
# @return [FalseClass]
|
144
142
|
def exclude_begin?
|
145
143
|
@exclude_begin
|
146
144
|
end
|
147
145
|
|
148
146
|
|
149
|
-
# Return the object equivalent to the Range part (namely, without the definition of exclude_begin?)
|
147
|
+
# Return the object equivalent to the {Range} part (namely, without the definition of {#exclude_begin?})
|
150
148
|
# @return [Range]
|
151
149
|
def rangepart
|
152
150
|
@rangepart ||= Range.new(self.begin, self.end, self.exclude_end?)
|
153
151
|
end
|
154
152
|
|
155
153
|
|
156
|
-
# Like Range, returns true only if it is either {
|
154
|
+
# Like {Range}, returns true only if it is either {Rangesmaller} or {Range}, and in addition if both {#exclude_begin?} and {#exclude_end?} match between the two objects.
|
155
|
+
# @return [Boolean]
|
157
156
|
def ==(r)
|
158
157
|
if defined? r.rangepart
|
159
158
|
rangepart = r.rangepart
|
@@ -175,7 +174,8 @@ class Rangesmaller < Range
|
|
175
174
|
alias :eql? :==
|
176
175
|
|
177
176
|
|
178
|
-
#
|
177
|
+
# See also {#cover?} and {Range#===}
|
178
|
+
# @return [Boolean]
|
179
179
|
def ===(obj)
|
180
180
|
# ("a".."z")===("cc") # => false
|
181
181
|
begin
|
@@ -199,9 +199,8 @@ class Rangesmaller < Range
|
|
199
199
|
alias :member? :===
|
200
200
|
|
201
201
|
|
202
|
-
#
|
203
|
-
#
|
204
|
-
# The following examples demonstrate what is going on.
|
202
|
+
# bsearch is internally implemented by converting a float into 64-bit integer.
|
203
|
+
# The following examples demonstrate what is going on.
|
205
204
|
#
|
206
205
|
# ary = [0, 4, 7, 10, 12]
|
207
206
|
# (3...4).bsearch{ |i| ary[i] >= 11} # => nil
|
@@ -226,16 +225,16 @@ class Rangesmaller < Range
|
|
226
225
|
# (Rational(36,10)..5).bsearch{|i| ary[i] >= 11} => # TypeError: can't do binary search for Rational (Ruby 2.1)
|
227
226
|
# (3..Rational(61,10)).bsearch{|i| ary[i] >= 11} => # TypeError: can't do binary search for Fixnum (Ruby 2.1)
|
228
227
|
#
|
229
|
-
#
|
230
|
-
#
|
231
|
-
#
|
232
|
-
#
|
233
|
-
#
|
228
|
+
# In short, bsearch works only with Integer and/or Float (as in Ruby 2.1).
|
229
|
+
# If either of begin and end is an Float, the search is conducted in Float and the returned value will be Float, unless nil.
|
230
|
+
# If Float, it searches on the binary plane.
|
231
|
+
# If Integer, the search is conducted on the descrete Integer points only,
|
232
|
+
# and no search will be made in between the adjascent integers.
|
234
233
|
#
|
235
|
-
#
|
236
|
-
#
|
237
|
-
#
|
238
|
-
#
|
234
|
+
# Given that, Rangesmaller#bsearch follows basically the same, even when exclude_begin? is true.
|
235
|
+
# If either end is Float, it searches between begin*(1+Float::EPSILON) and end.
|
236
|
+
# If both are Integer, it searches from begin+1.
|
237
|
+
# When {#exclude_begin?} is false, {Rangesmaller#bsearch} is identical to {Range#bsearch}.
|
239
238
|
#
|
240
239
|
def bsearch(*rest, &bloc)
|
241
240
|
if @exclude_begin
|
@@ -256,7 +255,7 @@ class Rangesmaller < Range
|
|
256
255
|
end # def bsearch(*rest, &bloc)
|
257
256
|
|
258
257
|
|
259
|
-
#
|
258
|
+
# See {#include?} or {#===}, and {Range#cover?}
|
260
259
|
def cover?(i)
|
261
260
|
# ("a".."z").cover?("cc") # => true
|
262
261
|
if @exclude_begin
|
@@ -275,30 +274,36 @@ class Rangesmaller < Range
|
|
275
274
|
end # def cover?(i)
|
276
275
|
|
277
276
|
|
278
|
-
# @raise [TypeError] If {#exclude_begin?} is true, and {#begin()
|
277
|
+
# @raise [TypeError] If {#exclude_begin?} is true, and {#begin}() or {#rangepart} does not have a method of {#succ}, then even if no block is given, this method raises TypeError straightaway.
|
278
|
+
# @return [Rangesmaller] self
|
279
|
+
# @return [Enumerator] if block is not given.
|
279
280
|
#
|
280
281
|
def each(*rest, &bloc)
|
281
282
|
# (1...3.5).each{|i|print i} # => '123' to STDOUT
|
282
283
|
# (1.3...3.5).each # => #<Enumerator: 1.3...3.5:each>
|
283
284
|
# (1.3...3.5).each{|i|print i} # => TypeError: can't iterate from Float
|
285
|
+
# Note: If the block is not given and if @exclude_begin is true, the self in the returned Enumerator is not the same as self here.
|
284
286
|
if @exclude_begin
|
285
287
|
if defined? self.begin.succ
|
286
|
-
Range.new(self.begin.succ,self.end,exclude_end?).send(__method__, *rest, &bloc)
|
288
|
+
ret = Range.new(self.begin.succ,self.end,exclude_end?).send(__method__, *rest, &bloc)
|
289
|
+
if block_given?
|
290
|
+
self
|
291
|
+
else
|
292
|
+
ret
|
293
|
+
end
|
287
294
|
else
|
288
295
|
raise TypeError, "can't iterate from "+self.begin.class.name
|
289
|
-
# if block_given?
|
290
296
|
end
|
291
297
|
else
|
292
298
|
super
|
293
299
|
end
|
294
|
-
self
|
295
300
|
end
|
296
301
|
|
297
302
|
|
298
|
-
# @param [Numeric] Optional. Must be non-negative. Consult {
|
299
|
-
# @note Like {
|
300
|
-
# However, if an argument is given (nb., acceptable since Ruby 1.9) when {#exclude_begin?} is true, it returns the array that starts from {#begin()
|
301
|
-
# @raise [TypeError] if the argument (Numeric) is given, yet if {#begin()
|
303
|
+
# @param [Numeric] Optional. Must be non-negative. Consult {Range#first} for detail.
|
304
|
+
# @note Like {Range#last}, if no argument is given, it behaves like {#begin()}, that is, it returns the initial value, regardless of {#exclude_begin?}.
|
305
|
+
# However, if an argument is given (nb., acceptable since Ruby 1.9) when {#exclude_begin?} is true, it returns the array that starts from {#begin}().succ().
|
306
|
+
# @raise [TypeError] if the argument (Numeric) is given, yet if {#begin}().succ is not defined.
|
302
307
|
#
|
303
308
|
def first(*rest)
|
304
309
|
# (1...3.1).last # => 3.1
|
@@ -351,7 +356,7 @@ class Rangesmaller < Range
|
|
351
356
|
end # def first(*rest)
|
352
357
|
|
353
358
|
|
354
|
-
# @note When {#exclude_begin?}
|
359
|
+
# @note When {#exclude_begin?} is true, the returned value is not strictly guaranteed to be unique, though in pracrtice it is most likely to be so.
|
355
360
|
#
|
356
361
|
def hash(*rest)
|
357
362
|
if @exclude_begin
|
@@ -362,6 +367,8 @@ class Rangesmaller < Range
|
|
362
367
|
end
|
363
368
|
|
364
369
|
|
370
|
+
# @return [String] eg., "(1<...5)", "(1<..5)", if {#exclude_begin?} is true,
|
371
|
+
# or else, identical to those for {Range}.
|
365
372
|
def inspect
|
366
373
|
if @exclude_begin
|
367
374
|
if exclude_end?
|
@@ -377,7 +384,7 @@ class Rangesmaller < Range
|
|
377
384
|
alias :to_s :inspect
|
378
385
|
|
379
386
|
|
380
|
-
#
|
387
|
+
# See {#first} for the definition when {#exclude_begin?} is true.
|
381
388
|
#
|
382
389
|
def min(*rest, &bloc)
|
383
390
|
# (1...3.5).max # => TypeError: cannot exclude non Integer end value
|
@@ -394,7 +401,7 @@ class Rangesmaller < Range
|
|
394
401
|
end
|
395
402
|
|
396
403
|
|
397
|
-
#
|
404
|
+
# See {#first} for the definition when {#exclude_begin?} is true.
|
398
405
|
#
|
399
406
|
def min_by(*rest, &bloc)
|
400
407
|
# (1...3.5).max # => TypeError: cannot exclude non Integer end value
|
@@ -411,7 +418,7 @@ class Rangesmaller < Range
|
|
411
418
|
end
|
412
419
|
|
413
420
|
|
414
|
-
#
|
421
|
+
# See {#first} for the definition when {#exclude_begin?} is true.
|
415
422
|
#
|
416
423
|
def minmax(*rest, &bloc)
|
417
424
|
# (0...3.5).minmax # => [0, 3]
|
@@ -433,7 +440,7 @@ class Rangesmaller < Range
|
|
433
440
|
end
|
434
441
|
|
435
442
|
|
436
|
-
#
|
443
|
+
# See {#first} for the definition when {#exclude_begin?} is true.
|
437
444
|
#
|
438
445
|
def minmax_by(*rest, &bloc)
|
439
446
|
# (0...3.5).minmax # => [0, 3]
|
@@ -454,8 +461,8 @@ class Rangesmaller < Range
|
|
454
461
|
end # def minmax_by(*rest)
|
455
462
|
|
456
463
|
|
457
|
-
#
|
458
|
-
# @see [ruby-list:49797] from matz for how {#size} behaves.
|
464
|
+
# See {#first} for the definition when {#exclude_begin?} is true.
|
465
|
+
# @see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/49797 [ruby-list:49797] from matz for how {#size} behaves (in Japanese).
|
459
466
|
#
|
460
467
|
def size(*rest)
|
461
468
|
# (1..5).size # => 5
|
@@ -505,19 +512,26 @@ class Rangesmaller < Range
|
|
505
512
|
end # def size
|
506
513
|
|
507
514
|
|
508
|
-
#
|
509
|
-
# @
|
515
|
+
# See {#each}.
|
516
|
+
# @raise [TypeError] If {#exclude_begin?} is true, and {#begin}() or {#rangepart} does not have a method of {#succ}, then even if no block is given, this method raises TypeError straightaway.
|
517
|
+
# @return [Rangesmaller] self
|
518
|
+
# @return [Enumerator] if block is not given.
|
510
519
|
#
|
511
520
|
def step(*rest, &bloc)
|
512
521
|
# (1...3.5).each{|i|print i} # => '123' to STDOUT
|
513
522
|
# (1.3...3.5).each # => #<Enumerator: 1.3...3.5:each>
|
514
523
|
# (1.3...3.5).each{|i|print i} # => TypeError: can't iterate from Float
|
524
|
+
# Note: If the block is not given and if @exclude_begin is true, the self in the returned Enumerator is not the same as self here.
|
515
525
|
if @exclude_begin
|
516
526
|
if defined? self.begin.succ
|
517
|
-
Range.new(self.begin.succ,self.end,exclude_end?).send(__method__, *rest, &bloc)
|
527
|
+
ret = Range.new(self.begin.succ,self.end,exclude_end?).send(__method__, *rest, &bloc)
|
528
|
+
if block_given?
|
529
|
+
self
|
530
|
+
else
|
531
|
+
ret
|
532
|
+
end
|
518
533
|
else
|
519
534
|
raise TypeError, "can't iterate from "+self.begin.class.name
|
520
|
-
# if block_given?
|
521
535
|
end
|
522
536
|
else
|
523
537
|
super
|
@@ -529,12 +543,14 @@ end # class Rangesmaller < Range
|
|
529
543
|
|
530
544
|
|
531
545
|
#
|
532
|
-
#=== Redefine a method {#==} so as to handle {
|
546
|
+
#=== Redefine a method {#==} so as to handle a comparison with {Rangesmaller}.
|
533
547
|
#
|
534
548
|
class Range
|
535
549
|
|
536
550
|
alias :eql_orig? :==
|
537
551
|
|
552
|
+
# When compared with a {Rangesmaller} object, it compares with {Rangesmaller#rangepart}.
|
553
|
+
# Namely, if {#begin}, {#end}, {#exclude_end?} agree between them and if {Rangesmaller#exclude_begin?} of the argument is false, it returns true, or false otherwise.
|
538
554
|
def eql?(r)
|
539
555
|
if defined? r.exclude_begin?
|
540
556
|
if r.exclude_begin?
|
data/rangesmaller.gemspec
CHANGED
data/test/test_rangesmaller.rb
CHANGED
@@ -287,8 +287,10 @@ p $LOADED_FEATURES.grep(/#{Regexp.quote(libfilebase)}$/)
|
|
287
287
|
assert_equal(@r12.reduce(:+), ns)
|
288
288
|
ns=0; @s21.each{|i| ns+=i}
|
289
289
|
assert_equal(((@ib+1)..@ie).reduce(:+), ns)
|
290
|
-
ns=0;
|
290
|
+
ns=0; ret=@s22.each{|i| ns+=i}
|
291
291
|
assert_equal(((@ib+1)...@ie).reduce(:+), ns)
|
292
|
+
assert_equal(@s22, ret)
|
293
|
+
assert(Enumerator === @s22.each)
|
292
294
|
|
293
295
|
## Arbitrary Class
|
294
296
|
sx1 = Rangesmaller.new(Xs.new(3), Xs.new(6), :exclude_begin => true, :exclude_end => true)
|
@@ -502,8 +504,10 @@ p $LOADED_FEATURES.grep(/#{Regexp.quote(libfilebase)}$/)
|
|
502
504
|
assert_equal(1+3+5, ns)
|
503
505
|
ns=0; @s21.step(2){|i| ns+=i}
|
504
506
|
assert_equal(2+4+6, ns)
|
505
|
-
ns=0;
|
507
|
+
ns=0; ret=@s22.step(2){|i| ns+=i}
|
506
508
|
assert_equal(2+4, ns)
|
509
|
+
assert_equal(@s22, ret)
|
510
|
+
assert(Enumerator === @s22.step(2))
|
507
511
|
|
508
512
|
## Arbitrary Class
|
509
513
|
sx1 = Rangesmaller.new(Xs.new(3), Xs.new(6), :exclude_begin => true, :exclude_end => true)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rangesmaller
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masa Sakano
|
@@ -51,3 +51,4 @@ specification_version: 4
|
|
51
51
|
summary: Rangesmaller class -- Range with include_begin?()
|
52
52
|
test_files:
|
53
53
|
- test/test_rangesmaller.rb
|
54
|
+
has_rdoc:
|