range_extd 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dae65a7801b819ebc7527acbbf1080c33b39f30b
4
- data.tar.gz: f242186b0e029594148cd3f09fd460fc0e8143ae
3
+ metadata.gz: e414692d4b21325679b022e9b1364ea3272a639a
4
+ data.tar.gz: 633ff4d1cba4c73fc523f1d6b0ec0272fcbf755e
5
5
  SHA512:
6
- metadata.gz: 7520c16da3bbfe5e13cb4c6d18553c412b6e34431704f4ba2f591549af3e712d285e821567cfa8f9bd597c09dcf4335a02d330085a9163adeb6b8ee4aef86025
7
- data.tar.gz: 10febe606e27681b7f7e4fdb43589f3127ba1a5cd976baa97b8ba09da506c63659b6c81d05af2fe76dec88a7df233fd99cbbcec0b48e05f177cb6a4978e90a3f
6
+ metadata.gz: f4ad1eeccabb65b819180c506a50a7763ec97d0a944548bf3ee62ba5ba766841853ec2677aa4f256dcdd0a1e668cad377dd1911190afba3cb020c6408eeeca70
7
+ data.tar.gz: 8f63b3abfde62792334c3e013de34dfa0c4d53c2b5f917631f7ba63891ae5a8868041fd58701da8d47ac20912b4cc7abbf910129e0f3184da5cedbb0f3046298
data/ChangeLog CHANGED
@@ -1,11 +1,23 @@
1
+ -----
2
+ (Version: 0.3.0)
3
+ 2014-05-02 Masa Saskano
4
+ * Added a String expression form of RangeExtd.new and RangeExtd.valid?(), modifying RangeExtd._get_init_args().
5
+
6
+ -----
7
+ 2014-05-01 Masa Sakano
8
+
9
+ * Fixed a bug that RangeExtd used to accept (nil...nil,true). Not any more.
10
+ * Added two class methods in RangeExtd: middle_strings=() and middle_strings().
11
+
1
12
  -----
2
13
  (Version: 0.2.0)
3
- 2014-04-29 Masa Saskano
14
+ 2014-04-29 Masa Sakano
15
+
4
16
  * Changed the name of a constant from RangeExtd::EVERYTHING to RangeExtd::ALL.
5
- Now accepts optional arguments in RangeExtd.new().
6
- Bug fix in RangeExtd#size when the begin is Float/Rational.
7
- Updated the embeded document in infinity.rb, mentioning about Time and Date classes.
8
- Added a text file News at the top directory.
17
+ * Now accepts optional arguments in RangeExtd.new().
18
+ * Bug fix in RangeExtd#size when the begin is Float/Rational.
19
+ * Updated the embeded document in infinity.rb, mentioning about Time and Date classes.
20
+ * Added a text file News at the top directory.
9
21
 
10
22
  -----
11
23
  (Version: 0.1.1)
data/News CHANGED
@@ -1,3 +1,9 @@
1
+ -----
2
+ (Version: 0.3.0) 2014-05-02
3
+ * Fixed a bug that RangeExtd used to accept (nil...nil,true). Not any more.
4
+ * Added two class methods in RangeExtd: middle_strings=() and middle_strings().
5
+ * Added a String expression form of RangeExtd.new().
6
+
1
7
  -----
2
8
  (Version: 0.2.0) 2014-04-29
3
9
  * Changed the name of a constant from RangeExtd::EVERYTHING to RangeExtd::ALL.
data/README.en.rdoc CHANGED
@@ -110,17 +110,23 @@ Here are some simple examples.
110
110
  (RangeExtd::Infinity::NEGATIVE..RangeExtd::Infinity::POSITIVE) \
111
111
  == RangeExtd::ALL # => true
112
112
 
113
- Basically, there are two forms:
113
+ Basically, there are three forms:
114
114
 
115
115
  RangeExtd(range, [exclude_begin=false, [exclude_end=false]], opts)
116
116
  RangeExtd(obj_begin, obj_end, [exclude_begin=false, [exclude_end=false]], opts)
117
+ RangeExtd(obj_begin, string_form, obj_end, [exclude_begin=false, [exclude_end=false]], opts)
117
118
 
118
119
  The two parameters in the brackets specify the respective boundary to be excluded if true,
119
120
  or included if false (Default). If they contradict to the first
120
121
  parameter of the range (Range or RangeExtd), those latter two parameters are used.
121
122
  Also, you can specify the same parameters as the options <tt>:exclude_begin</tt>
122
123
  and <tt>:exclude_end</tt>, which have the highest priority, if specified.
124
+ The <tt>string_form</tt> in the third form is like ".." and "<...", which can be
125
+ defined by a user (see {RangeExtd.middle_strings=}() for detail), and is arguably
126
+ the most visibly recognisable way for any range with <tt>exclude_begin=true</tt>.
127
+
123
128
  <tt>RangeExtd.new()</tt> is the same thing.
129
+ For more detail and examples, see {RangeExtd.new}.
124
130
 
125
131
 
126
132
  === Slightly more advanced uses
@@ -199,21 +205,23 @@ The former represents the empty range and the latter does the range
199
205
  covers everything, namely open-ended for the both negative and
200
206
  positive directions.
201
207
 
202
- In addition to all the standard methods of Range, the following
203
- methods are added to both RangeExtd and Range classes.
208
+ In addition to all the standard methods of {Range}, the following
209
+ methods are added to both {RangeExtd} and {Range} classes.
204
210
  See the document of each method for detail (some are defined only in
205
- Range class, as RangeExtd inherits it).
211
+ {Range} class, as {RangeExtd} inherits it).
206
212
 
207
- * <tt>exclude_begin?</tt>
213
+ * <tt>exclude_begin?</tt> (not defined in {Range} class)
208
214
  * <tt>valid?</tt>
209
215
  * <tt>empty?</tt>
210
216
  * <tt>null?</tt>
211
217
  * <tt>is_none?</tt>
212
218
  * <tt>is_all?</tt>
213
219
 
214
- There is a class method, which is equivalent to the instance
215
- method <tt>valid?</tt>.
220
+ There are three class methods, the first of which is equivalent
221
+ to the instance method <tt>valid?</tt>:
216
222
  * <tt>RangeExtd.valid?</tt>
223
+ * <tt>RangeExtd.middle_strings=(ary)</tt>
224
+ * <tt>RangeExtd.middle_strings</tt>
217
225
 
218
226
  What is valid (<tt>#valid?</tt> => true) as a range is defined as follows.
219
227
 
data/README.ja.rdoc CHANGED
@@ -110,17 +110,24 @@ Here are some simple examples.
110
110
  (RangeExtd::Infinity::NEGATIVE..RangeExtd::Infinity::POSITIVE) \
111
111
  == RangeExtd::ALL # => true
112
112
 
113
- Basically, there are two forms:
113
+ Basically, there are three forms:
114
114
 
115
115
  RangeExtd(range, [exclude_begin=false, [exclude_end=false]], opts)
116
116
  RangeExtd(obj_begin, obj_end, [exclude_begin=false, [exclude_end=false]], opts)
117
+ RangeExtd(obj_begin, string_form, obj_end, [exclude_begin=false, [exclude_end=false]], opts)
117
118
 
118
119
  The two parameters in the brackets specify the respective boundary to be excluded if true,
119
120
  or included if false (Default). If they contradict to the first
120
121
  parameter of the range (Range or RangeExtd), those latter two parameters are used.
121
122
  Also, you can specify the same parameters as the options <tt>:exclude_begin</tt>
122
123
  and <tt>:exclude_end</tt>, which have the highest priority, if specified.
124
+ The <tt>string_form</tt> in the third form is like ".." and "<...", which can be
125
+ defined by a user (see {RangeExtd.middle_strings=}() for detail), and is arguably
126
+ the most visibly recognisable way for any range with <tt>exclude_begin=true</tt>.
127
+
123
128
  <tt>RangeExtd.new()</tt> is the same thing.
129
+ For more detail and examples, see {RangeExtd.new}.
130
+
124
131
 
125
132
  === Slightly more advanced uses
126
133
 
@@ -198,21 +205,23 @@ The former represents the empty range and the latter does the range
198
205
  covers everything, namely open-ended for the both negative and
199
206
  positive directions.
200
207
 
201
- In addition to all the standard methods of Range, the following
202
- methods are added to both RangeExtd and Range classes.
208
+ In addition to all the standard methods of {Range}, the following
209
+ methods are added to both {RangeExtd} and {Range} classes.
203
210
  See the document of each method for detail (some are defined only in
204
- Range class, as RangeExtd inherits it).
211
+ {Range} class, as {RangeExtd} inherits it).
205
212
 
206
- * <tt>exclude_begin?</tt>
213
+ * <tt>exclude_begin?</tt> (not defined in {Range} class)
207
214
  * <tt>valid?</tt>
208
215
  * <tt>empty?</tt>
209
216
  * <tt>null?</tt>
210
217
  * <tt>is_none?</tt>
211
218
  * <tt>is_all?</tt>
212
219
 
213
- There is a class method, which is equivalent to the instance
214
- method <tt>valid?</tt>.
220
+ There are three class methods, the first of which is equivalent
221
+ to the instance method <tt>valid?</tt>:
215
222
  * <tt>RangeExtd.valid?</tt>
223
+ * <tt>RangeExtd.middle_strings=(ary)</tt>
224
+ * <tt>RangeExtd.middle_strings</tt>
216
225
 
217
226
  What is valid (<tt>#valid?</tt> => true) as a range is defined as follows.
218
227
 
@@ -434,10 +443,11 @@ Versions:: The versions of this package follow Semantic Versioning (2.0.0) http:
434
443
  (RangeExtd::Infinity::NEGATIVE..RangeExtd::Infinity::POSITIVE) \
435
444
  == RangeExtd::ALL # => true
436
445
 
437
- インスタンスを作成するのには、二通りあります。
446
+ インスタンスを作成するのには、三通りあります。
438
447
 
439
448
  RangeExtd(range, [exclude_begin=false, [exclude_end=false]], opts)
440
449
  RangeExtd(obj_begin, obj_end, [exclude_begin=false, [exclude_end=false]], opts)
450
+ RangeExtd(obj_begin, string_form, obj_end, [exclude_begin=false, [exclude_end=false]], opts)
441
451
 
442
452
  大括弧の中の二つのパラメーターが、それぞれ始点と終点とを除外する(true)、または含む
443
453
  (false)を指示します。もし、その二つのパラメーターが最初のパラメーターのレンジ
@@ -445,7 +455,12 @@ Versions:: The versions of this package follow Semantic Versioning (2.0.0) http:
445
455
  ます。同じパラメーターをオプションHash
446
456
  (<tt>:exclude_begin</tt> と <tt>:exclude_end</tt>)で指定することもできて、
447
457
  もし指定されればそれらが最高の優先度を持ちます。
458
+ 第三の方法の <tt>string_form</tt> とは、".." や "<..."のことで、ユーザー定義
459
+ も可能です(詳しくは {RangeExtd.middle_strings=}() を参照のこと)。これが、
460
+ 視覚的には最もわかりやすい方法かも知れません。
461
+
448
462
  <tt>RangeExtd.new()</tt> も上と同意味です。
463
+ さらなる解説及び例は、{RangeExtd.new}を参照して下さい。
449
464
 
450
465
 
451
466
  === 少し上級編
@@ -522,19 +537,22 @@ RangeExtd のインスタンスは、 Rangeと同じくイミュータブルで
522
537
 
523
538
  前者は、空レンジを表し、後者は全てを含むレンジ、すなわち正負両方向に開いたレンジを表します。
524
539
 
525
- Rangeクラスの通常のメソッド全てに加え、以下が RangeExtd と Rangeクラス両方に加え
540
+ {Range}クラスの通常のメソッド全てに加え、以下が {RangeExtd}{Range}クラス両方に加え
526
541
  られています。詳細は、各メソッドのマニュアルを参照下さい(注: 幾つかのメソッドは
527
- Rangeクラスのみで定義されていて、 RangeExtd はそれを継承しています)。
542
+ {Range}クラスのみで定義されていて、 {RangeExtd} はそれを継承しています)。
528
543
 
529
- * <tt>exclude_begin?</tt>
544
+ * <tt>exclude_begin?</tt> ({Range}クラスでは未定義)
530
545
  * <tt>valid?</tt>
531
546
  * <tt>empty?</tt>
532
547
  * <tt>null?</tt>
533
548
  * <tt>is_none?</tt>
534
549
  * <tt>is_all?</tt>
535
550
 
536
- インスタンスメソッドの <tt>valid?</tt> に等価なクラスメソッドも一つあります。
551
+ クラスメソッドが三つあります。一番上のものは、
552
+ インスタンスメソッドの <tt>valid?</tt> に等価です。
537
553
  * <tt>RangeExtd.valid?</tt>
554
+ * <tt>RangeExtd.middle_strings=(ary)</tt>
555
+ * <tt>RangeExtd.middle_strings</tt>
538
556
 
539
557
  何がレンジとして有効 (<tt>#valid?</tt> => true) かの定義は以下です。
540
558
 
@@ -75,7 +75,7 @@ class RangeExtd < Range
75
75
  # is immediately comparable with the {RangeExtd::Infinity} instances,
76
76
  # YourComparable.new <=> RangeExtd::Infinity::POSITIVE # => -1
77
77
  # RangeExtd::Infinity::POSITIVE <=> YourComparable.new # => 1
78
- # except for the infinity inscances in YourComparable (see #{==}).
78
+ # except for the infinity inscances in YourComparable (see {#==}).
79
79
  #
80
80
  # See the document in {Object#<=>} in this code/package for detail.
81
81
  #
@@ -98,7 +98,7 @@ class RangeExtd < Range
98
98
  # {#===}, {#==}, {#<=>}, {#succ}, {#to_s}, {#inspect},
99
99
  # {#infinity?}, {#positive?} and {#negative?}.
100
100
  #
101
- # Note that the unary operand {#-@} is not defined.
101
+ # Note that the unary operand [#-@] is not defined.
102
102
  #
103
103
  class Infinity
104
104
 
@@ -77,14 +77,26 @@ end
77
77
  #
78
78
  class RangeExtd < Range
79
79
 
80
+ @@middle_strings = []
81
+
80
82
  # @note The flag of exclude_begin|end can be given in the arguments in a couple of ways.
81
83
  # If there is any duplication, those specified in the optional hash have the highest
82
84
  # priority. Then the two descrete Boolean parameters have the second.
83
- # If not, the values embeded in the {Range} or {RangeExtd} object
85
+ # If not, the values embeded in the {Range} or {RangeExtd} object or the String form
84
86
  # in the parameter are used. In default, both of them are false.
85
87
  #
88
+ # @example
89
+ # RangeExtd(1...2)
90
+ # RangeExtd(1..3, true)
91
+ # RangeExtd(2..3, :exclude_begin => true)
92
+ # RangeExtd(1, 4, false, true)
93
+ # RangeExtd(1,'<...',5)
94
+ # RangeExtd.middle_strings = :math
95
+ # RangeExtd(2,'<x<=',5)
96
+ # RangeExtd(RangeExtd::Infinity::NEGATIVE..RangeExtd::Infinity::POSITIVE)
97
+ #
86
98
  # @overload new(range, [exclude_begin=false, [exclude_end=false]], opts)
87
- # @param [Object] range Instance of Range or its subclasses, including RangeExtd
99
+ # @param [Object] range Instance of {Range} or its subclasses, including {RangeExtd}
88
100
  # @param exclude_begin [Boolean] If specified, this has the higher priority, or false in default.
89
101
  # @param exclude_end [Boolean] If specified, this has the higher priority, or false in default.
90
102
  # @option opts [Boolean] :exclude_begin If specified, this has the highest priority, or false in default.
@@ -98,8 +110,19 @@ class RangeExtd < Range
98
110
  # @option opts [Boolean] :exclude_begin If specified, this has the higher priority, or false in default.
99
111
  # @option opts [Boolean] :exclude_end If specified, this has the higher priority, or false in default.
100
112
  #
101
- # Note no possible opts are defined at present.
102
- # Any opts given as Hash are simply ignored.
113
+ # @overload new(obj_begin, string_form, obj_end, [exclude_begin=false, [exclude_end=false]], opts)
114
+ # @param obj_begin [Object] Any object that is {Comparable} with end
115
+ # @param string_form [Object] String form (without pre/postfix) of range expression set by {RangeExtd.middle_strings=}()
116
+ # @param obj_end [Object] Any object that is Comparable with begin
117
+ # @param exclude_begin [Boolean] If specified, this has the lower priority, or false in default.
118
+ # @param exclude_end [Boolean] If specified, this has the lower priority, or false in default.
119
+ # @option opts [Boolean] :exclude_begin If specified, this has the higher priority, or false in default.
120
+ # @option opts [Boolean] :exclude_end If specified, this has the higher priority, or false in default.
121
+ #
122
+ # Note if you use the third form with "string_form" with the user-defined string
123
+ # (via {RangeExtd.middle_strings=}()), make 100 per cent sure
124
+ # of what you are doing. If the string is ambiguous, the result may differ
125
+ # from what you thought you would get! See {RangeExtd.middle_strings=}() for detail.
103
126
  #
104
127
  # @raise [ArgumentError] particularly if the range to be created is not {#valid?}.
105
128
  def initialize(*inar, **hsopt) # **k expression from Ruby 1.9?
@@ -397,7 +420,7 @@ class RangeExtd < Range
397
420
  end # def cover?(i)
398
421
 
399
422
 
400
- # @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.
423
+ # @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.
401
424
  # @return [RangeExtd] self
402
425
  # @return [Enumerator] if block is not given.
403
426
  #
@@ -425,10 +448,10 @@ class RangeExtd < Range
425
448
  end
426
449
 
427
450
 
428
- # Like {Range#last}, if no argument is given, it behaves like {#begin()}, that is, it returns the initial value, regardless of {#exclude_begin?}.
451
+ # Like {Range#last}, if no argument is given, it behaves like {#begin}(), that is, it returns the initial value, regardless of {#exclude_begin?}.
429
452
  # 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().
430
- # @raise [TypeError] if the argument (Numeric) is given and if {#exclude_begin?} is true, yet if {#begin}().succ is not defined, or yet if {#none}?
431
- # @param [Integer] Optional. Must be non-negative. Consult {Range#first} for detail.
453
+ # @raise [TypeError] if the argument (Numeric) is given and if {#exclude_begin?} is true, yet if {#begin}().succ is not defined, or yet if {#is_none?}
454
+ # @param rest [Integer] Optional. Must be non-negative. Consult {Range#first} for detail.
432
455
  # @return [Object] if no argument is given, equivalent to {#end}.
433
456
  # @return [Array] if an argument is given.
434
457
  def first(*rest)
@@ -693,7 +716,7 @@ class RangeExtd < Range
693
716
 
694
717
 
695
718
  # See {#each}.
696
- # @raise [TypeError] If {#exclude_begin?} is true, and {#begin}() does not have the method {#succ}, then even if no block is given, this method raises TypeError straightaway.
719
+ # @raise [TypeError] If {#exclude_begin?} is true, and {#begin}() does not have the method [#succ], then even if no block is given, this method raises TypeError straightaway.
697
720
  # @return [RangeExtd] self
698
721
  # @return [Enumerator] if block is not given.
699
722
  #
@@ -722,14 +745,18 @@ class RangeExtd < Range
722
745
  end
723
746
 
724
747
 
748
+ ##################################################
749
+ # Class methods
750
+ ##################################################
751
+
725
752
  # Private class method to evaluate the arguments.
726
753
  def self._get_init_args(*inar, **hsopt)
727
- nMin = 1; nMax = 4
754
+ nMin = 1; nMax = 5
728
755
  if inar.size < nMin || nMax < inar.size
729
756
  raise ArgumentError, "wrong number of arguments (#{inar.size} for #{nMin}..#{nMax})"
730
757
  end
731
758
 
732
- hsFlag = { :prm1st => nil }
759
+ hsFlag = { :prm1st => nil, :excl_offset => nil }
733
760
  if defined? inar[0].exclude_begin?
734
761
  hsFlag[:prm1st] = :rangeextd
735
762
  elsif defined? inar[0].exclude_end?
@@ -754,8 +781,8 @@ class RangeExtd < Range
754
781
  exclude_end = inar[0].exclude_end?
755
782
  end
756
783
 
757
- if inar.size > 3
758
- nMin = 1; nMax = 3
784
+ nMin = 1; nMax = 3
785
+ if inar.size > nMax
759
786
  raise ArgumentError, "wrong number of arguments (#{inar.size} for #{nMin}..#{nMax})"
760
787
  end
761
788
 
@@ -764,19 +791,61 @@ class RangeExtd < Range
764
791
  # @rangepart = Range.new(inar[0].begin, inar[0].end, exclude_end)
765
792
 
766
793
  when :object
767
- if inar.size > 2
768
- exclude_begin = (true ^! inar[2])
769
- else
770
- exclude_begin = false
794
+ nMin = 2; nMax = 5
795
+ if inar.size < 2
796
+ raise ArgumentError, "wrong number of arguments (#{inar.size} for #{nMin}..#{nMax})"
771
797
  end
772
798
 
773
- if inar.size > 3
774
- exclude_end = (true ^! inar[3])
799
+ # Default: assuming the form (obj_begin, obj_end, [excl_begin, [excl_end]])
800
+ beginend = [inar[0], inar[1]]
801
+ hsFlag[:excl_offset] = 0
802
+ exclude_begin = false
803
+ exclude_end = false
804
+
805
+ # Now, checking if the form is the String one, and if so, process it.
806
+ arMid = @@middle_strings.map{|i| Regexp.quote(i)} # See self.middle_strings=(ary) for description.
807
+ if inar.size > 2 && defined?(inar[1].=~)
808
+ begin
809
+ cmp = (inar[0] <=> inar[2]).abs
810
+ rescue
811
+ cmp = nil
812
+ end
813
+ if ((cmp == 0)||(cmp == 1)) && (inar[1] =~ /^(#{arMid[1]}|#{arMid[2]})#{arMid[3]}(#{arMid[4]}|#{arMid[5]})$/)
814
+ # The form is (obj_begin, midStr, obj_end, [excl_begin, [excl_end]])
815
+ # Hence all the default values are overwritten.
816
+ beginend = [inar[0], inar[2]]
817
+ hsFlag[:excl_offset] = 1
818
+ if $1 == @@middle_strings[1]
819
+ exclude_begin = false
820
+ else
821
+ exclude_begin = true
822
+ end
823
+ if $2 == @@middle_strings[4]
824
+ exclude_end = true
825
+ else
826
+ exclude_end = false
827
+ end
828
+ else
829
+ nMin = 2; nMax = 4
830
+ if inar.size > nMax
831
+ raise ArgumentError, "wrong number of arguments (#{inar.size} for #{nMin}..#{nMax})"
832
+ end
833
+ end
775
834
  else
776
- exclude_end = false
835
+ nMin = 2; nMax = 4
836
+ if inar.size > nMax
837
+ raise ArgumentError, "wrong number of arguments (#{inar.size} for #{nMin}..#{nMax})"
838
+ end
839
+ end
840
+
841
+ if inar.size > 2+hsFlag[:excl_offset]
842
+ exclude_begin = (true ^! inar[2+hsFlag[:excl_offset]]) # 3rd or 4th argument
843
+ end
844
+
845
+ if inar.size > 3+hsFlag[:excl_offset]
846
+ exclude_end = (true ^! inar[3+hsFlag[:excl_offset]]) # 4th or 5th argument
777
847
  end
778
848
 
779
- beginend = [inar[0], inar[1]]
780
849
  # arRet = [inar[0], inar[1], exclude_end, exclude_begin]
781
850
  # @rangepart = Range.new(inar[0], inar[1], exclude_end)
782
851
 
@@ -804,7 +873,7 @@ class RangeExtd < Range
804
873
  # This routine is also impremented as a method in {Range},
805
874
  # and accordingly its sub-classes.
806
875
  #
807
- # This routine is called from {RangeExtd#new}, hence
876
+ # This routine is called from {RangeExtd.new}, hence
808
877
  # for any instance of {RangeExtd} class, its {#valid?} returns true.
809
878
  #
810
879
  # What is valid is defined as follows:
@@ -852,29 +921,24 @@ class RangeExtd < Range
852
921
  # If not, the values embeded in the {Range} or {RangeExtd} object
853
922
  # in the parameter are used. In default, both of them are false.
854
923
  #
855
- # @overload new(range, [exclude_begin=false, [exclude_end=false]], opts)
924
+ # @overload new(range, [exclude_begin=false, [exclude_end=false]])
856
925
  # @param [Object] range Instance of Range or its subclasses, including RangeExtd
857
926
  # @param exclude_begin [Boolean] If specified, this has the higher priority, or false in default.
858
927
  # @param exclude_end [Boolean] If specified, this has the higher priority, or false in default.
859
- # @option opts [Boolean] :exclude_begin If specified, this has the highest priority, or false in default.
860
- # @option opts [Boolean] :exclude_end If specified, this has the highest priority, or false in default.
861
928
  #
862
- # @overload new(obj_begin, obj_end, [exclude_begin=false, [exclude_end=false]], opts)
929
+ # @overload new(obj_begin, obj_end, [exclude_begin=false, [exclude_end=false]])
863
930
  # @param obj_begin [Object] Any object that is {Comparable} with end
864
931
  # @param obj_end [Object] Any object that is Comparable with begin
865
932
  # @param exclude_begin [Boolean] If specified, this has the lower priority, or false in default.
866
933
  # @param exclude_end [Boolean] If specified, this has the lower priority, or false in default.
867
- # @option opts [Boolean] :exclude_begin If specified, this has the higher priority, or false in default.
868
- # @option opts [Boolean] :exclude_end If specified, this has the higher priority, or false in default.
869
934
  #
870
- def self.valid?(*inar, **hsopt)
935
+ def self.valid?(*inar)
871
936
  (vbeg, vend, exc_beg, exc_end) = _get_init_args(*inar)
872
937
 
873
- if (vbeg.nil? && vend.nil? && exc_beg && exc_end)
874
- return true # equivalent to self.is_none?
875
- # But this routine is called from new(), hence is_none?() is not used.
938
+ if defined?(inar[0].is_none?) && inar[0].is_none? && exc_beg && exc_end
939
+ return true
876
940
  end
877
-
941
+
878
942
  begin
879
943
  t = (vbeg <=> vend)
880
944
  begin
@@ -912,11 +976,119 @@ class RangeExtd < Range
912
976
  end # def valid?
913
977
 
914
978
 
979
+ # Set the class variable to be used in {RangeExtd#to_s} and {RangeExtd#inspect}
980
+ # to configure the format of their returned values.
981
+ #
982
+ # The parameters should be given as an Array with 7 elements of string
983
+ # in principle, which gives the characters for each index:
984
+ # 0. prefix
985
+ # 1. begin-inclusive
986
+ # 2. begin-exclusive
987
+ # 3. middle-string to bridge both ends
988
+ # 4. end-exclusive
989
+ # 5. end-inclusive
990
+ # 6. postfix
991
+ #
992
+ # If the elements [1] and [2], or [4] and [5] are equal,
993
+ # a warning is issued as some of {RangeExtd} in display will be indistinguishable.
994
+ # Note even if no warning is issued, that does not mean all the forms
995
+ # will be not ambiguous. For example, if you specify
996
+ # ['(', '', '.', '..', '.', '', ')']
997
+ # a string (3...7) can mean either exclusive {#begin} or {#end}.
998
+ # It is user's responsibility to make it right.
999
+ #
1000
+ # The two most popular forms can be given as a Symbol instead of Array, that is,
1001
+ # :default ( ['', '', '<', '..', '.', '', ''] )
1002
+ # :math ( ['', '<=', '<', 'x', '<', '<=', ''] )
1003
+ #
1004
+ # @param ary [Array, Symbol]
1005
+ # @return [Array, Symbol]
1006
+ #
1007
+ # @example
1008
+ # RangeExtd.middle_strings=:default # Default
1009
+ # RangeExtd(2...6).to_s # => "2...6"
1010
+ # RangeExtd(2,6,1).to_s # => "2<..6"
1011
+ # RangeExtd.middle_strings=:math
1012
+ # RangeExtd(2...6).to_s # => "2<=x<6"
1013
+ # RangeExtd(2,6,1).to_s # => "2<x<=6"
1014
+ # RangeExtd.middle_strings=['[','(in)','(ex)',', ','(ex)','(in)',']']
1015
+ # RangeExtd(2...6).to_s # => "[2(in), (ex)6]"
1016
+ # RangeExtd(2,6,1).to_s # => "[2(ex), (in)6]"
1017
+ #
1018
+ def self.middle_strings=(ary)
1019
+ case ary
1020
+ when :default
1021
+ @@middle_strings = ['', '', '<', '..', '.', '', '']
1022
+ when :math
1023
+ @@middle_strings = ['', '<=', '<', 'x', '<', '<=', '']
1024
+ else
1025
+ begin
1026
+ if ary.size == 7
1027
+ _dummy = 'a' + ary[6]
1028
+ @@middle_strings = ary
1029
+ if (ary[1] == ary[2]) || (ary[4] == ary[5])
1030
+ warn "warning: some middle_strings are indistinguishable."
1031
+ end
1032
+ else
1033
+ raise
1034
+ end
1035
+ rescue
1036
+ raise ArgumentError, "invalid argument"
1037
+ end
1038
+ end
1039
+ end
1040
+
1041
+ # See {RangExtd.middle_strings=}() for detail.
1042
+ #
1043
+ # @return [Array<String>]
1044
+ def self.middle_strings()
1045
+ @@middle_strings
1046
+ end
1047
+
1048
+ self.middle_strings=:default # Initialisation
1049
+
1050
+ ##################################################
915
1051
  private
1052
+ ##################################################
916
1053
 
917
1054
  # Core routine for {#inspect} and {#to_s}
918
1055
  # @param [Symbol] method the method name.
919
1056
  def re_inspect_core(method)
1057
+ # 0. prefix
1058
+ # 1. begin-inclusive
1059
+ # 2. begin-exclusive
1060
+ # 3. middle-string to bridge both ends
1061
+ # 4. end-exclusive
1062
+ # 5. end-inclusive
1063
+ # 6. postfix
1064
+
1065
+ midStr = ''
1066
+ if @exclude_begin
1067
+ midStr += @@middle_strings[2]
1068
+ else
1069
+ midStr += @@middle_strings[1]
1070
+ end
1071
+ midStr += @@middle_strings[3]
1072
+ if @exclude_end
1073
+ midStr += @@middle_strings[4]
1074
+ else
1075
+ midStr += @@middle_strings[5]
1076
+ end
1077
+
1078
+ if is_none?
1079
+ strBegin = 'Null' # Null<...Null
1080
+ strEnd = 'Null'
1081
+ else
1082
+ strBegin = self.begin.send(method)
1083
+ strEnd = self.end.send(method)
1084
+ end
1085
+
1086
+ @@middle_strings[0] + strBegin + midStr + strEnd + @@middle_strings[6]
1087
+ end # def re_inspect_core(method)
1088
+
1089
+ # Core routine for {#inspect} and {#to_s}
1090
+ # @param [Symbol] method the method name.
1091
+ def re_inspect_core_orig(method)
920
1092
  if @exclude_end
921
1093
  midStr = "..."
922
1094
  else
@@ -929,7 +1101,7 @@ class RangeExtd < Range
929
1101
  else
930
1102
  self.begin.send(method) + midStr + self.end.send(method)
931
1103
  end
932
- end # def re_inspect_core(method)
1104
+ end # def re_inspect_core_orig(method)
933
1105
 
934
1106
 
935
1107
  # Core routine for {#===} and {#eql?}
@@ -1028,9 +1200,9 @@ class Range
1028
1200
  # use them;
1029
1201
  # (1...1).valid? # => false
1030
1202
  # On the other hand, {RangeExtd} class does not accept or create
1031
- # any invalid range; for any {RangeExtd} object, {RangeExtd#valid}
1203
+ # any invalid range; for any {RangeExtd} object, RangeExtd#valid?
1032
1204
  # returns true. For example, there is no {RangeExtd} object
1033
- # that is expressed as (1...1) (See {#valid} for detail).
1205
+ # that is expressed as (1...1) (See {#valid?} for detail).
1034
1206
  #
1035
1207
  # For that reason, when those non-valid Range objects are compared
1036
1208
  # with a {RangeExtd} object, the returned value may not be what
@@ -1039,7 +1211,7 @@ class Range
1039
1211
  # The former is an invalid range, while the latter is
1040
1212
  # a rigidly-defined empty range.
1041
1213
  #
1042
- # Consult {#valid} and {RangeExtd#==} for more detail.
1214
+ # Consult {#valid?} and {RangeExtd#==} for more detail.
1043
1215
  def ==(r)
1044
1216
  equal_core(r, :==, :equal_prerangeextd?)
1045
1217
  end
@@ -1071,7 +1243,7 @@ class Range
1071
1243
  # RangeExtd::ALL.valid? # => true
1072
1244
  #
1073
1245
  # @note By definition, all the {RangeExtd} instances are valid,
1074
- # because {RangeExtd#new} checks the validity.
1246
+ # because {RangeExtd.new} checks the validity.
1075
1247
  def valid?
1076
1248
  RangeExtd.valid?(self)
1077
1249
  end # def valid?
@@ -1085,17 +1257,17 @@ class Range
1085
1257
  #
1086
1258
  # 1. the range must be valid: {#valid?} => true
1087
1259
  # 2. if the range id discrete, that is, {#begin} has
1088
- # {#succ} method, there must be no member within the range:
1260
+ # [#succ] method, there must be no member within the range:
1089
1261
  # {#to_a}.empty? => true
1090
1262
  # 3. if the range is continuous, that is, {#begin} does not have
1091
- # {#succ} method, {#begin} and {#end} must be equal
1263
+ # [#succ] method, {#begin} and {#end} must be equal
1092
1264
  # (({#begin} <=> {#end}) => 0) and both the boundaries must
1093
1265
  # be excluded: ({#exclude_begin?} && {#exclude_end?}) => true.
1094
1266
  # Note that ranges with equal {#begin} and {#end} with
1095
1267
  # inconsistent two exclude status are not valid, and the built-in
1096
1268
  # Range always has the {#begin}-exclude status of false.
1097
1269
  #
1098
- # In these conditions, none of Range instance would return true in {#empty}.
1270
+ # In these conditions, none of Range instance would return true in {#empty?}.
1099
1271
  #
1100
1272
  # @example
1101
1273
  # (nil..nil).empty? # => nil
@@ -1108,7 +1280,7 @@ class Range
1108
1280
  # RangeExtd::NONE.empty? # => true
1109
1281
  #
1110
1282
  # @note to check whether it is either empty or invalid, use {#null?}.
1111
- # See {#valid?} and {RangeExtd.valid}, too.
1283
+ # See {#valid?} and {RangeExtd.valid?}, too.
1112
1284
  #
1113
1285
  # @return [Boolean, nil]
1114
1286
  def empty?
@@ -1222,7 +1394,7 @@ end # class Range
1222
1394
 
1223
1395
 
1224
1396
  # Constant-form of {#RangeExtd}.
1225
- # {#RangeExtd(*)} is equivalent to {#RangeExtd.new}.
1397
+ # #RangeExtd(*) is equivalent to {#RangeExtd.new}.
1226
1398
  #
1227
1399
  def RangeExtd(*rest, &b)
1228
1400
  RangeExtd.new(*rest, &b)
data/range_extd.gemspec CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{range_extd}
5
- s.version = "0.2.0"
5
+ s.version = "0.3.0"
6
6
  # s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
7
7
  # s.executables << 'hola'
8
8
  # s.bindir = 'bin'
9
9
  s.authors = ["Masa Sakano"]
10
- s.date = %q{2014-04-29}
10
+ s.date = %q{2014-05-02}
11
11
  s.summary = %q{RangeExtd - Extended Range class with exclude_begin and open-ends}
12
12
  s.description = %q{Package for a subclass of Range, RangeExtd and RangeExtd::Infinity. The former defines a range that enables an exclusion of the begin boundary, in addition to the end boundary as in the built-in Range, and accepts open-ended ranges to infinity for either (or both) positive/negative direction. The latter has the two constant objects, POSITIVE and NEGATIVE, and they are a generalised Infinity of Float::INFINITY to any Comparable objects.}
13
13
  # s.email = %q{abc@example.com}
@@ -281,6 +281,71 @@ return
281
281
  assert_equal(-@ib, j22.end)
282
282
  end
283
283
 
284
+ def test_new_middle_strings
285
+ aru = ['[','(in)','(ex)',', ','(ex)','(in)',']']
286
+ ark = [nil, :math, aru, :default]
287
+
288
+ ars = ['..', '<=x<=', aru[1]+aru[3]+aru[5]]; ars.push(ars[0])
289
+ ark.each_index do |i|
290
+ RangeExtd.middle_strings = ark[i] if ! ark[i].nil?
291
+ k11 = RangeExtd.new(@ib, ars[i], @ie)
292
+ assert !k11.exclude_begin?
293
+ assert !k11.exclude_end?
294
+ assert_equal @ib, k11.begin
295
+ assert_equal @ie, k11.end
296
+ end
297
+
298
+ ars = ['...', '<=x<', aru[1]+aru[3]+aru[4]]; ars.push(ars[0])
299
+ ark.each_index do |i|
300
+ RangeExtd.middle_strings = ark[i] if ! ark[i].nil?
301
+ k12 = RangeExtd.new(@ib, ars[i], @ie)
302
+ assert !k12.exclude_begin?
303
+ assert k12.exclude_end?
304
+ assert_equal @ib, k12.begin
305
+ assert_equal @ie, k12.end
306
+ end
307
+
308
+ ars = ['<..', '<x<=', aru[2]+aru[3]+aru[5]]; ars.push(ars[0])
309
+ ark.each_index do |i|
310
+ RangeExtd.middle_strings = ark[i] if ! ark[i].nil?
311
+ k21 = RangeExtd.new(@ib, ars[i], @ie)
312
+ assert k21.exclude_begin?
313
+ assert !k21.exclude_end?
314
+ assert_equal @ib, k21.begin
315
+ assert_equal @ie, k21.end
316
+ end
317
+
318
+ ars = ['<...', '<x<', aru[2]+aru[3]+aru[4]]; ars.push(ars[0])
319
+ ark.each_index do |i|
320
+ RangeExtd.middle_strings = ark[i] if ! ark[i].nil?
321
+ k22 = RangeExtd.new(@ib, ars[i], @ie)
322
+ assert k22.exclude_begin?
323
+ assert k22.exclude_end?
324
+ assert_equal @ib, k22.begin
325
+ assert_equal @ie, k22.end
326
+ end
327
+
328
+ l12 = RangeExtd.new(@ib, '..', @ie, true)
329
+ assert l12.exclude_begin?
330
+ assert !l12.exclude_end?
331
+ assert_equal @ib, l12.begin
332
+ assert_equal @ie, l12.end
333
+
334
+ m22 = RangeExtd.new(-@ie, '..', -@ib, true, true)
335
+ assert m22.exclude_begin?
336
+ assert m22.exclude_end?
337
+ assert_equal(-@ie, m22.begin)
338
+ assert_equal(-@ib, m22.end)
339
+
340
+ assert_raises(ArgumentError){ RangeExtd.new(@ib, '....', @ie) } # => the argument can not consist of a RangeExtd instance.
341
+ RangeExtd.middle_strings = :math
342
+ assert_raises(ArgumentError){ RangeExtd.new(@ib, '..', @ie) } # => the argument can not consist of a RangeExtd instance.
343
+ RangeExtd.middle_strings = :default
344
+ assert_raises(ArgumentError){ RangeExtd.new(@ib, '..', @ie, T, nil, T) } # => wrong number of arguments (6 for 1..5)
345
+ assert_raises(ArgumentError){ RangeExtd.new(@ib, @ie, T, nil, T) } # => wrong number of arguments (5 for 2..4)
346
+ assert_raises(ArgumentError){ RangeExtd.new(@ib) } # => wrong number of arguments (1 for 2..5)
347
+ end # def test_new_middle_strings
348
+
284
349
  def test_new_const
285
350
  assert_equal @s22, RangeExtd(@r12, true)
286
351
  end
@@ -685,6 +750,7 @@ return
685
750
  assert_equal(2, RangeExtd(0, ary.size).bsearch{|i| ary[i] >= 6})
686
751
  # http://www.ruby-doc.org/core-2.1.1/Range.html#method-i-bsearch
687
752
 
753
+ assert_equal(3, RangeExtd(1..4).bsearch{ |i| ary[i] >= 9}) # (1..4).bsearch{|i| ary[i] >= 9} => 3
688
754
  assert_equal(nil, RangeExtd(3...4).bsearch{ |i| ary[i] >= 11})
689
755
  assert_equal(nil, RangeExtd(3.6...4).bsearch{|i| ary[i] >= 11})
690
756
  assert_equal(4, RangeExtd(3...5).bsearch{ |i| ary[i] >= 11})
@@ -967,6 +1033,12 @@ return
967
1033
  end
968
1034
 
969
1035
 
1036
+ def test_RangeExtdClass_valid
1037
+ assert !RangeExtd.valid?(nil, nil, 9,9) # All 3 were true up to Version 0.1.0
1038
+ assert !RangeExtd.valid?(nil...nil,9,9)
1039
+ assert !RangeExtd.valid?(nil..nil, 9,9)
1040
+ end # def test_RangeExtdClass_valid
1041
+
970
1042
  def test_Range_valid
971
1043
  assert RangeExtd::NONE.valid?
972
1044
  assert RangeExtd::ALL.valid?
@@ -1171,7 +1243,7 @@ return
1171
1243
 
1172
1244
 
1173
1245
  # Tests of all the examples in the document.
1174
- def test_indocument
1246
+ def test_in_document
1175
1247
  # RangeExtd#initialize
1176
1248
  r = RangeExtd(5...8, true)
1177
1249
  assert r.exclude_begin? # => true
@@ -1283,6 +1355,35 @@ return
1283
1355
  assert RangeExtd.valid?(RangeExtd::Infinity::NEGATIVE..?d, true) # => false
1284
1356
  # Note the last example may change in the future release.
1285
1357
 
1358
+ # RangeExtd.middle_strings=
1359
+ arDef = ['', '', '<', '..', '.', '', '']
1360
+ assert_equal arDef, RangeExtd.middle_strings
1361
+ assert_equal "2...6", RangeExtd(2...6).to_s
1362
+ assert_equal "2<..6", RangeExtd(2,6,1).to_s
1363
+ assert_equal "2...6", RangeExtd(2...6).inspect
1364
+ assert_equal "2<..6", RangeExtd(2,6,1).inspect
1365
+ assert_equal 'a...c', RangeExtd(?a...?c).to_s
1366
+ assert_equal 'a<..c', RangeExtd(?a,?c,1).to_s
1367
+ assert_equal '"a"..."c"', RangeExtd(?a...?c).inspect
1368
+ assert_equal '"a"<.."c"', RangeExtd(?a,?c,1).inspect
1369
+
1370
+ RangeExtd.middle_strings=:math
1371
+ assert_equal ['', '<=', '<', 'x', '<', '<=', ''], RangeExtd.middle_strings
1372
+ assert_equal "2<=x<6", RangeExtd(2...6).to_s
1373
+ assert_equal "2<x<=6", RangeExtd(2,6,1).to_s
1374
+ ar=['[','(in)','(ex)',', ','(ex)','(in)',']']
1375
+
1376
+ RangeExtd.middle_strings=ar
1377
+ assert_equal ar, RangeExtd.middle_strings
1378
+ assert_equal "[2(in), (ex)6]", RangeExtd(2...6).to_s
1379
+ assert_equal "[2(ex), (in)6]", RangeExtd(2,6,1).to_s
1380
+
1381
+ RangeExtd.middle_strings=:default # Default
1382
+ assert_equal arDef, RangeExtd.middle_strings
1383
+ assert_equal ['', '', '<', '..', '.', '', ''], RangeExtd.middle_strings
1384
+ assert_equal "2...6", RangeExtd(2...6).to_s
1385
+ assert_equal "2<..6", RangeExtd(2,6,1).to_s
1386
+
1286
1387
  # Range.==
1287
1388
  assert !(1...1).valid?
1288
1389
  assert !(nil...nil).valid?
@@ -1313,7 +1414,7 @@ return
1313
1414
  assert_equal 1, (RangeExtd::Infinity::POSITIVE <=> ?z)
1314
1415
  assert_equal nil, (50 <=> RangeExtd::Infinity::POSITIVE)
1315
1416
  assert_equal 1, (RangeExtd::Infinity::POSITIVE <=> 50)
1316
- end
1417
+ end # def test_in_document
1317
1418
 
1318
1419
  # def test_RangeExtd_special
1319
1420
  # # Positive Infinity (== 'z')
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: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masa Sakano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-29 00:00:00.000000000 Z
11
+ date: 2014-05-02 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