range_extd 0.3.0 → 0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e414692d4b21325679b022e9b1364ea3272a639a
4
- data.tar.gz: 633ff4d1cba4c73fc523f1d6b0ec0272fcbf755e
2
+ SHA256:
3
+ metadata.gz: 9e1551349faa64451f2d3cb0d0105e0e36d031822fd6d614ff6c641be3ae6091
4
+ data.tar.gz: 9cfe5dce8e2e887bd8536c37e6e81e47566c477158cdecc5e4dba4ed48aed058
5
5
  SHA512:
6
- metadata.gz: f4ad1eeccabb65b819180c506a50a7763ec97d0a944548bf3ee62ba5ba766841853ec2677aa4f256dcdd0a1e668cad377dd1911190afba3cb020c6408eeeca70
7
- data.tar.gz: 8f63b3abfde62792334c3e013de34dfa0c4d53c2b5f917631f7ba63891ae5a8868041fd58701da8d47ac20912b4cc7abbf910129e0f3184da5cedbb0f3046298
6
+ metadata.gz: fed26ea14419c50417d319f54e1fc40d33e5fd95d92f2e19b110c6ebb001fb86581097de95c4551e1d50a4c4919e9c33ffef11a2c8837ffc03f3413cf6a091cf
7
+ data.tar.gz: e3cd288b44a7d42c9a8b8e947cb4bf030e4b906096bd779d304690708815e8eeabf916893ab334456a69a153504e73364f57e9a5167607b73d64f02f372fb5e4
@@ -0,0 +1,55 @@
1
+ # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile '~/.gitignore_global'
6
+
7
+ # Ignore bundler config.
8
+ /.bundle
9
+ /vendor/bundle
10
+
11
+ # Ignore all logfiles and tempfiles.
12
+ /log/*
13
+ /tmp/*
14
+ !/log/.keep
15
+ !/tmp/.keep
16
+
17
+ .rbenv-version
18
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
19
+ .rvmrc
20
+
21
+ /node_modules
22
+ /yarn-error.log
23
+
24
+ .byebug_history
25
+
26
+ *.[oa]
27
+ *.so
28
+ *~
29
+ *.nogem
30
+ *nogem.*
31
+ *.bak
32
+ *.BAK
33
+ *.backup
34
+ *.org
35
+ *.orig
36
+ *.elc
37
+ *.pyc
38
+ \#*\#
39
+ .\#*
40
+
41
+ # Elastic Beanstalk Files
42
+ .elasticbeanstalk/*
43
+ !.elasticbeanstalk/*.cfg.yml
44
+ !.elasticbeanstalk/*.global.yml
45
+
46
+ # macOS
47
+ .DS_Store
48
+
49
+ # yard
50
+ *.yardoc
51
+
52
+ # Ruby Gem doc
53
+ *.gem
54
+ doc/*
55
+
data/ChangeLog CHANGED
@@ -1,6 +1,19 @@
1
+ -----
2
+ (Version: 0.4)
3
+ 2019-10-30 Masa Sakano
4
+ * Many minor bug fixes (mostly suppressing Warnings) to catch up with Ruby 2.6.
5
+ * Because quite a few (boundary) behaviours have changed from previous versions a few years ago, such as the comparison between two INFINITY.
6
+ * Endless range not yet fully incorporated.
7
+
8
+ -----
9
+ (Version: 0.4.0)
10
+ 2014-05-10 Masa Saskano
11
+ * Added Range#equiv? and RangeExtd#equiv? methods.
12
+
1
13
  -----
2
14
  (Version: 0.3.0)
3
- 2014-05-02 Masa Saskano
15
+ 2014-05-02 Masa Sakano
16
+
4
17
  * Added a String expression form of RangeExtd.new and RangeExtd.valid?(), modifying RangeExtd._get_init_args().
5
18
 
6
19
  -----
@@ -0,0 +1,23 @@
1
+ ALL =
2
+
3
+ objs =
4
+
5
+ .SUFFIXES: .so .o .c .f
6
+
7
+ #.o.so:
8
+ # ${LD} ${LFLAGS} -o $@ $< ${LINK_LIB}
9
+
10
+ all: ${ALL}
11
+
12
+
13
+ .PHONY: clean test doc
14
+ clean:
15
+ $(RM) bin/*~
16
+
17
+ ## You may need RUBYLIB=`pwd`/lib:$RUBYLIB
18
+ test:
19
+ rake test
20
+
21
+ doc:
22
+ yard doc; [[ -x ".github" && ( "README.ja.rdoc" -nt ".github/README.md" ) ]] && ( ruby -r rdoc -e 'puts RDoc::Markup::ToMarkdown.new.convert ARGF.read' < README.ja.rdoc > .github/README.md ; echo ".github/README.md is updated." ) || exit 0
23
+
data/News CHANGED
@@ -1,3 +1,7 @@
1
+ -----
2
+ (Version: 0.4.0) 2014-05-10
3
+ * Added Range#equiv? method.
4
+
1
5
  -----
2
6
  (Version: 0.3.0) 2014-05-02
3
7
  * Fixed a bug that RangeExtd used to accept (nil...nil,true). Not any more.
@@ -22,6 +22,7 @@ For example, <tt>(3...3).valid?</tt> returns false, because the element 3 is
22
22
  inclusive for the begin boundary, yet exclusive for the end boundary,
23
23
  which are contradictory to each other. With this RangeExtd class,
24
24
  it is expressed as a valid range,
25
+
25
26
  * RangeExtd.new(3, 3, true, true) # => an empty range
26
27
  * RangeExtd.new(3, 3, false, false) # => a single-point range (3..3)
27
28
 
@@ -31,12 +32,15 @@ so it is completely compatible with the standard Ruby.
31
32
  To express open-ended ranges is simple; you just use either of
32
33
  the two (negative and positive, or former and later) constants
33
34
  defined in the class {RangeExtd::Infinity}
35
+
34
36
  * RangeExtd::Infinity::NEGATIVE
35
37
  * RangeExtd::Infinity::POSITIVE
36
38
 
37
39
  They are basically the object that generalised <tt>Float::INFINITY</tt> to
38
40
  any Comparable object. For example,
41
+
39
42
  ("a"..RangeExtd::Infinity::POSITIVE).each
43
+
40
44
  gives an infinite iterator with <tt>String#succ</tt>, starting from "a"
41
45
  (therefore, make sure to code so it breaks the iterator at one stage!).
42
46
 
@@ -64,10 +68,19 @@ I hope you find it to be useful.
64
68
 
65
69
  ==== NOTE: Relationship with Rangesmaller
66
70
 
67
- This package supercedes the obsolete Rangesmaller package and class,
71
+ This package supercedes the obsolete {Rangesmaller}[https://rubygems.org/gems/rangesmaller] package and class,
68
72
  with the added open-ended feature, and a different interface in
69
73
  creating a new instance.
70
- {https://rubygems.org/gems/rangesmaller}
74
+ https://rubygems.org/gems/rangesmaller
75
+
76
+ ==== NOTE: Relationship with Rangeary
77
+
78
+ The class to handle multiple Ranges with objects of the same class
79
+ (most typically Float),
80
+ {Rangeary}[https://rubygems.org/gems/rangeary] uses this library to
81
+ fullest, because the concept of potentially open-ended Range ato both
82
+ begin and end is essential to realise Rangeary.
83
+ https://rubygems.org/gems/rangeary
71
84
 
72
85
 
73
86
  == Install
@@ -75,19 +88,28 @@ creating a new instance.
75
88
  gem install range_extd
76
89
 
77
90
  Two files
91
+
78
92
  range_extd/range_extd.rb
79
93
  range_extd/infinity/infinity.rb
94
+
80
95
  should be installed in one of your <tt>$LOAD_PATH</tt>
81
96
 
82
97
  Alternatively get it from
98
+
83
99
  http://rubygems.org/gems/range_extd
84
100
 
85
101
  Then all you need to do is
102
+
86
103
  require 'range_extd/range_extd'
104
+
87
105
  or, possibly as follows, if you manually install it
106
+
88
107
  require 'range_extd'
108
+
89
109
  in your Ruby script (or irb). The other file
110
+
90
111
  range_extd/infinity/infinity.rb
112
+
91
113
  is called (required) from it automatically.
92
114
 
93
115
  Have fun!
@@ -126,7 +148,7 @@ defined by a user (see {RangeExtd.middle_strings=}() for detail), and is arguabl
126
148
  the most visibly recognisable way for any range with <tt>exclude_begin=true</tt>.
127
149
 
128
150
  <tt>RangeExtd.new()</tt> is the same thing.
129
- For more detail and examples, see {RangeExtd.new}.
151
+ For more detail and examples, see {RangeExtd.initialize}.
130
152
 
131
153
 
132
154
  === Slightly more advanced uses
@@ -147,6 +169,7 @@ For more detail and examples, see {RangeExtd.new}.
147
169
  RangeExtd(?a, ?e, true, true).empty? # => false
148
170
  RangeExtd::NONE.is_none? # => true
149
171
  RangeExtd::ALL.is_all? # => true
172
+ (3...7).equiv?(3..6) # => true
150
173
 
151
174
  All the methods that are in the built-in Range can be used.
152
175
 
@@ -173,7 +196,9 @@ They are the objects that generalise the concept of
173
196
  to any Comparable objects. The methods <tt><=></tt> and <tt>succ</tt> are defined.
174
197
 
175
198
  You can use them the same as other objects, such as,
199
+
176
200
  ("k"..RangeExtd::Infinity::POSITIVE)
201
+
177
202
  However as they do not have any other methods,
178
203
  the use out of Range-type class is probably meaningless.
179
204
 
@@ -216,9 +241,11 @@ See the document of each method for detail (some are defined only in
216
241
  * <tt>null?</tt>
217
242
  * <tt>is_none?</tt>
218
243
  * <tt>is_all?</tt>
244
+ * <tt>equiv?</tt>
219
245
 
220
246
  There are three class methods, the first of which is equivalent
221
247
  to the instance method <tt>valid?</tt>:
248
+
222
249
  * <tt>RangeExtd.valid?</tt>
223
250
  * <tt>RangeExtd.middle_strings=(ary)</tt>
224
251
  * <tt>RangeExtd.middle_strings</tt>
@@ -281,20 +308,28 @@ existing code in principle.
281
308
 
282
309
  == Known bugs
283
310
 
284
- * <tt>hash()</tt> method does not always guarantee to return a unique
285
- and exclusive number for the equal RangeExtd object, though such an
286
- exception is extremely unlikely to happen in reality.
287
-
288
- Note this library does not work in Ruby 1.8 or earlier.
289
- For Ruby 1.9.3 it is probably all right, however I have never tested
290
- it.
311
+ * As of Ruby 2.6, {Endless Range}[https://rubyreferences.github.io/rubychanges/2.6.html#endless-range-1]
312
+ is introduced. As a result, Range#end sometimes raises RangeError.
313
+ However, this library does not yet take it into account, and it may
314
+ raises Exception when encountering an endless Range.
315
+ * Note this library does not work in Ruby 1.8 or earlier.
316
+ For Ruby 1.9.3 it is probably all right, though I have never tested it.
317
+ * Some unusual (rare) boundary conditions are found to vary from
318
+ version to version in Ruby, such as a comparison between
319
+ Float::INFINITY-s. Though the test scripts are pretty extensive,
320
+ they have not been performed over many different versions of Ruby.
321
+ In some versions, some features may not work well, although such
322
+ occasions should be very rare.
323
+ * {RangeExtd#hash} method does not theoretically guarantee to return a unique
324
+ number for a {RangeExtd} object, though to encounter a hash number that is
325
+ used elsewhere is extremely unlikely to happen in reality.
291
326
 
292
327
  Extensive tests have been performed, as included in the package.
293
328
 
294
329
 
295
330
  == ToDo
296
331
 
297
- Nothing planned.
332
+ * Handle the Ruby-2.6 new feature {Endless Range}[https://rubyreferences.github.io/rubychanges/2.6.html#endless-range-1].
298
333
 
299
334
 
300
335
  == Final notes
@@ -334,3 +369,355 @@ License:: MIT.
334
369
  Warranty:: No warranty whatsoever.
335
370
  Versions:: The versions of this package follow Semantic Versioning (2.0.0) http://semver.org/
336
371
 
372
+
373
+
374
+ = RangeExtd - 拡張Rangeクラス - exclude_begin と無限大に開いた範囲と
375
+
376
+ このパッケージは、Range を拡張した RangeExtd クラスを定義しています。
377
+ 以下の特徴を持ちます。
378
+
379
+ 1. メソッド exclude_begin? の導入 (レンジの始点を除外できる),
380
+ 2. (無限大に)開いたレンジ
381
+ 3. NONE (空レンジ) と ALL (全範囲レンジ)定数の導入
382
+ 4. 初めて自己論理的に完結したレンジ構造の達成
383
+ 5. 組込Rangeとの完全後方互換性
384
+
385
+ 組込Rangeにある exclude_end に加えて、exclude_beginを導入したこと、及
386
+ び無限大へ開いた範囲を許可したことで、一次元上の範囲の論理的完全性を実
387
+ 現しました。
388
+
389
+ これにより、レンジの有効性を厳密に定義しています。それに従って、数個の
390
+ メソッドを Range及び(自然に)そのサブクラスに追加しました。なかでも特徴的なのが、
391
+ {Range#valid?} と {Range#empty?} です。
392
+
393
+ たとえば、<tt>(3...3).valid?</tt> は偽を返します。要素の 3 が、始点と
394
+ しては含まれているのに対し、終点としては除外されていて、これは相互に矛
395
+ 盾しているためです。ここで導入する RangeExtdクラスにおいては、以下のよ
396
+ うにこれが有効なレンジとして定義できます。
397
+
398
+ * RangeExtd.new(3, 3, true, true) # => 空レンジ
399
+ * RangeExtd.new(3, 3, false, false) # => 一点レンジ (3..3)
400
+
401
+ しかしながら、組込Rangeの範囲内に収まっている限り、何も変わっていませ
402
+ ん。つまり、標準の Rubyとの完全な後方互換性を実現しています。
403
+
404
+ 無限に開いたレンジを表すのは簡単です。単に {RangeExtd::Infinity}クラスで
405
+ 定義されている二つの定数(無限大または無現小、あるいは無限前と無限後)の
406
+ いずれかを用います。
407
+
408
+ * RangeExtd::Infinity::NEGATIVE
409
+ * RangeExtd::Infinity::POSITIVE
410
+
411
+ これらは基本的に <tt>Float::INFINITY</tt> を全ての Comparableであるオ
412
+ ブジェクトに一般化したものです。たとえば、
413
+
414
+ ("a"..RangeExtd::Infinity::POSITIVE).each
415
+
416
+ は、"a"から始まる <tt>String#succ</tt> を使った無限のイテレーターを与えます
417
+ (だから、どこかで必ず breakするようにコードを書きましょう!)。
418
+
419
+ 組込 Rangeは大変有用なクラスであり、Rubyユーザーに容易なプログラミングを可能にす
420
+ るツールでした。しかし、始点を除外することができないのが玉に瑕でありました。
421
+
422
+ ただし、それにはれっきとした理由があることは分かります。Rubyの Rangeは、Numeric
423
+ (厳密にはその実数を表現したもの)だけに限ったものではありません。 <tt>succ()</tt> メソッ
424
+ ドを持つオブジェクトによる Rangeは極めて有用です。一方、<tt>succ()</tt> の逆に相
425
+ 当するメソッドは一般的には定義されていません。そういう意味で、Rangeは本質的に非
426
+ 対称です。加えて、よく使われる Rangeオブジェクトのうちあるもの(たとえば Float)は
427
+ 連続的なのに対し、そうでないものも普通です(たとえば Integer や String)。この状況
428
+ が厳密な定義をする時の混乱に拍車をかけています。
429
+
430
+ ここで始点を除外可能としたことは、そういう意味で、道筋が100パーセント明らかなも
431
+ のではありませんでした。ここで私が採用した RangeExtdクラスの定義は、おそらく、考え
432
+ られる唯一のものではないでしょう。とはいえ、個人的には満足のいくものに仕上がりま
433
+ したし、このレンジという枠内での論理的完全性をうまく達成できたと思います。
434
+
435
+ このクラスが少なからぬ人に有用なものであることを願ってここにリリースします。
436
+
437
+
438
+ ==== 注: Rangesmallerとの関係
439
+
440
+ このパッケージは、(今やサポートされていない) {Rangesmaller}[https://rubygems.org/gems/rangesmaller] パッケージ及びクラスを
441
+ 後継するものです。同クラスの機能に、無限に開いた範囲を許す機能が加わり、また、オ
442
+ ブジェクト生成時のインターフェースが変更されています。
443
+ https://rubygems.org/gems/rangesmaller
444
+
445
+ ==== 注: Rangearyとの関係
446
+
447
+ 同クラス(典型的にはFloat)のオブジェクトからなる複数のRangeを扱うクラス
448
+ {Rangeary}[https://rubygems.org/gems/rangeary] は、本ライブラリを使い
449
+ 切っています。Rangeを実現するためには、始端と終端との両方で開いた可能
450
+ 性があるRangeを扱うことが必須だからです。
451
+ https://rubygems.org/gems/rangeary
452
+
453
+ == インストール
454
+
455
+ gem install range_extd
456
+
457
+ により、ファイルが 2個、
458
+
459
+ range_extd/range_extd.rb
460
+ range_extd/infinity/infinity.rb
461
+
462
+ <tt>$LOAD_PATH</tt> の一カ所にインストールされるはずです。
463
+
464
+ あるいは、パッケージを以下から入手できます。
465
+
466
+ http://rubygems.org/gems/range_extd
467
+
468
+ 後は、Ruby のコード(又は irb)から
469
+
470
+ require 'range_extd/range_extd'
471
+
472
+ とするだけです。もしくは、特に手でインストールした場合は、
473
+
474
+ require 'range_extd'
475
+
476
+ とする必要があるかも知れません。もう一方のファイル
477
+
478
+ range_extd/infinity/infinity.rb
479
+
480
+ は、自動的に読み込まれます。
481
+
482
+ お楽しみあれ!
483
+
484
+
485
+ == 単純な使用例
486
+
487
+ === RangeExtd インスタンスを作成する方法
488
+
489
+ 以下に幾つかの基本的な使用例を列挙します。
490
+
491
+ r = RangeExtd(?a...?d, true) # => a<...d
492
+ r.exclude_begin? # => true
493
+ r.to_a # => ["b", "c"]
494
+ RangeExtd(1...2) == (1...2) # => true
495
+ RangeExtd(1, 2, false, true)== (1...2) # => true
496
+ RangeExtd(1, 1, false, false)==(1..1) # => true
497
+ RangeExtd(1, 1, true, true) == RangeExtd::NONE # => true
498
+ RangeExtd(1, 1, false, true) # => ArgumentError
499
+ (RangeExtd::Infinity::NEGATIVE..RangeExtd::Infinity::POSITIVE) \
500
+ == RangeExtd::ALL # => true
501
+
502
+ インスタンスを作成するのには、三通りあります。
503
+
504
+ RangeExtd(range, [exclude_begin=false, [exclude_end=false]], opts)
505
+ RangeExtd(obj_begin, obj_end, [exclude_begin=false, [exclude_end=false]], opts)
506
+ RangeExtd(obj_begin, string_form, obj_end, [exclude_begin=false, [exclude_end=false]], opts)
507
+
508
+ 大括弧の中の二つのパラメーターが、それぞれ始点と終点とを除外する(true)、または含む
509
+ (false)を指示します。もし、その二つのパラメーターが最初のパラメーターのレンジ
510
+ (Range or RangeExtd) と矛盾する場合は、ここで与えた二つのパラメーターが優先され
511
+ ます。同じパラメーターをオプションHash
512
+ (<tt>:exclude_begin</tt> と <tt>:exclude_end</tt>)で指定することもできて、
513
+ もし指定されればそれらが最高の優先度を持ちます。
514
+ 第三の方法の <tt>string_form</tt> とは、".." や "<..."のことで、ユーザー定義
515
+ も可能です(詳しくは {RangeExtd.middle_strings=}() を参照のこと)。これが、
516
+ 視覚的には最もわかりやすい方法かも知れません。
517
+
518
+ <tt>RangeExtd.new()</tt> も上と同意味です。
519
+ さらなる解説及び例は、{RangeExtd.initialize}を参照して下さい。
520
+
521
+
522
+ === 少し上級編
523
+
524
+ (1..RangeExtd::Infinity::POSITIVE).each do |i|
525
+ print i
526
+ break if i >= 9
527
+ end # => self ( "123456789" => STDOUT )
528
+ (nil..nil).valid? # => false
529
+ (1...1).valid? # => false
530
+ (1...1).null? # => true
531
+ RangeExtd.valid?(1...1) # => false
532
+ RangeExtd(1, 1, true, true).valid? # => true
533
+ RangeExtd(1, 1, true, true).empty? # => true
534
+ RangeExtd(?a, ?b, true, true).to_a? # => []
535
+ RangeExtd(?a, ?b, true, true).empty? # => true
536
+ RangeExtd(?a, ?e, true, true).to_a? # => ["b", "c", "d"]
537
+ RangeExtd(?a, ?e, true, true).empty? # => false
538
+ RangeExtd::NONE.is_none? # => true
539
+ RangeExtd::ALL.is_all? # => true
540
+ (3...7).equiv?(3..6) # => true
541
+
542
+ 組込Rangeに含まれる全てのメソッドが使用可能です。
543
+
544
+
545
+ == 詳説
546
+
547
+ ファイル range_extd.rb が読まれた段階で、次の二つのクラスが定義されます。
548
+
549
+ * RangeExtd
550
+ * RangeExtd::Infinity
551
+
552
+ 加えて、Range クラスに数個のメソッドが追加また改訂されます。Rangeクラスに加えら
553
+ れる改変は、全て後方互換性を保っています。
554
+
555
+ === RangeExtd::Infinity クラス
556
+
557
+ {RangeExtd::Infinity} クラスは、基本、定数二つのみを保持するものです。
558
+
559
+ * RangeExtd::Infinity::NEGATIVE
560
+ * RangeExtd::Infinity::POSITIVE
561
+
562
+ これらは、 <tt>Float::INFINITY</tt> を全ての Comparable なオブジェクトに一般化し
563
+ たものです。メソッド <tt><=></tt> と <tt>succ</tt> が定義されています。
564
+
565
+ これらは、他のオブジェクトと同様に普通に使用可能です。たとえば、
566
+ ("k"..RangeExtd::Infinity::POSITIVE)
567
+ とはいえ、他には何もメソッドを持っていないため、 Range型のクラスの中以外での使用
568
+ はおそらく意味がないでしょう。
569
+
570
+ なお、Numericのオブジェクトに対しては、原則として <tt>Float::INFINITY</tt> の方
571
+ を使って下さい。
572
+
573
+ ユーザー定義のどの Comparable なクラスに属するどのオブジェクトも、これら二定数と
574
+ 可換的に比較可能です。その際、同クラスに置ける比較メソッドがマナー良く書かれてあ
575
+ る、という前提で。
576
+
577
+ さらに詳しくは、マニュアルを参照して下さい(YARD または RDoc形式で書かれた文書が
578
+ コード内部に埋込まれていますし、それが RubyGemsのウェブサイトでも閲覧できます。
579
+
580
+
581
+ === RangeExtd クラス
582
+
583
+ RangeExtd のインスタンスは、 Rangeと同じくイミュータブルです。だから、一度インス
584
+ タンスが生成されると、変化しません。
585
+
586
+ インスタンスの生成方法は上述の通りです(「使用例」の章)。レンジとして"valid"(後述)と見
587
+ なされないインスタンスを生成しようとすると、例外(<tt>ArgumentError</tt>)が発生し、
588
+ 失敗します。
589
+
590
+ このクラスには、二つの定数が定義されています。
591
+
592
+ * RangeExtd::NONE
593
+ * RangeExtd::ALL
594
+
595
+ 前者は、空レンジを表し、後者は全てを含むレンジ、すなわち正負両方向に開いたレンジを表します。
596
+
597
+ {Range}クラスの通常のメソッド全てに加え、以下が {RangeExtd} と {Range}クラス両方に加え
598
+ られています。詳細は、各メソッドのマニュアルを参照下さい(注: 幾つかのメソッドは
599
+ {Range}クラスのみで定義されていて、 {RangeExtd} はそれを継承しています)。
600
+
601
+ * <tt>exclude_begin?</tt> ({Range}クラスでは未定義)
602
+ * <tt>valid?</tt>
603
+ * <tt>empty?</tt>
604
+ * <tt>null?</tt>
605
+ * <tt>is_none?</tt>
606
+ * <tt>is_all?</tt>
607
+ * <tt>equiv?</tt>
608
+
609
+ クラスメソッドが三つあります。一番上のものは、
610
+ インスタンスメソッドの <tt>valid?</tt> に等価です。
611
+
612
+ * <tt>RangeExtd.valid?</tt>
613
+ * <tt>RangeExtd.middle_strings=(ary)</tt>
614
+ * <tt>RangeExtd.middle_strings</tt>
615
+
616
+ 何がレンジとして有効 (<tt>#valid?</tt> => true) かの定義は以下です。
617
+
618
+ 1. 始点と終点とが互いに Comparable であり、かつその比較結果に矛盾がないこと。
619
+ この唯一の例外は {RangeExtd::NONE} で、これは valid です。
620
+ たとえば、<tt>(nil..nil)</tt> は valid では「ありません」(参考までに、この例は
621
+ Ruby 1.8 では例外を生じていました)。
622
+ 2. 始点は終点と等しい(<tt>==</tt>)か小さくなければなりません。すなわし、
623
+ <tt>(begin <=> end)</tt> は、-1 または 0 を返すこと。
624
+ 3. もし始点と終点とが等しい時、すなわち <tt>(begin <=> end) == 0</tt>ならば、
625
+ 端を除外するかどうかのフラグは両端で一致していなければなりません。
626
+ すなわち、もし始点が除外ならば、終点も除外されていなくてはならず、逆も真です。
627
+ その一例として、 <tt>(1...1)</tt> は、"valid" では「ありません」。なぜならば
628
+ 組込レンジでは、始点を常に含むからです。
629
+
630
+ さらなる詳細は {RangeExtd.valid?} と {Range#valid?} のマニュアルを
631
+ 参照して下さい。
632
+
633
+ 何がレンジとして空(<tt>#empty?</tt> => true)かの定義は以下の通りです。
634
+
635
+ 1. レンジは、valid であること: <tt>valid?</tt> => true
636
+ 2. もしレンジの要素が離散的であれば、すなわち始点の要素がメソッド <tt>succ</tt>
637
+ を持っていれば、レンジ内部に要素が一つも無いことが条件(当然、始点のフラグ
638
+ は除外になっていなければなりません): <tt>to_a.empty?</tt> => true
639
+ 3. もしレンジが連続的であれば、すなわち始点の要素がメソッド <tt>succ</tt> を持っ
640
+ ていなければ、始点と終点とが等しく (<tt>(begin <=> end)</tt> => 0)、かつ両端
641
+ のフラグが除外になっていること: <tt>(exclude_begin? && exclude_end?)</tt> => true.
642
+
643
+ なお、始点と終点とが等しい一方でその除外フラグが一致しない場合は、前節で述べたよ
644
+ うに "valid"ではありません。組込レンジは、始点除外フラグが常に偽(<tt>false</tt>)で
645
+ す。そのため、組込Rangeのオブジェクトで、<tt>empty?</tt> が真(<tt>true</tt>)にな
646
+ ることはありません。
647
+
648
+ さらなる詳細は {Range#empty?} のマニュアルを
649
+ 参照して下さい。
650
+
651
+
652
+ 最後、 {Range#null?} は、「<tt>empty?</tt> または "valid"でない」ことに等
653
+ 価です。従って、 RangeExtd オブジェクトにとっては、<tt>null?</tt> は
654
+ <tt>empty?</tt> に等価です。
655
+
656
+ RangeExtd と別の RangeExtd または Rangeの比較 (<tt><=></tt>) においては、これら
657
+ の定義が考慮されます。そのうちの幾つかは、上の「使用例」の項に示されています。
658
+ さらなる詳細は {Range#==}、{RangeExtd#==} および
659
+ <tt>#eql?</tt> のマニュアルを参照して下さい。
660
+
661
+ なお、処理が Rangeオブジェクト内部で閉じている限り、その振舞いは標準 Rubyと同一
662
+ で、互換性を保っています。したがって、このライブラリを読込むことで既存のコードに
663
+ 影響を与えることは原理的にないはずです。
664
+
665
+
666
+ == 既知のバグ
667
+
668
+
669
+ * Ruby 2.6 では、後ろに無限に開いたRange({Endless Range}[https://rubyreferences.github.io/rubychanges/2.6.html#endless-range-1])
670
+ が導入されました。本ライブラリでは、まだそれには対応していません。
671
+ したがって、Endless Rangeを本クラスに適用した場合、問題が起きるでしょう。
672
+ * このライブラリは Ruby 1.8 およびそれ以前のバージョンでは動作しません。
673
+ Ruby 1.9.3 ではおそらく大丈夫でしょうが、私は試したことがありません。
674
+ * いくつかの極めて稀な境界条件に於ける挙動は、Rubyのバージョンごとにあ
675
+ る程度変化しています。例えば、Float::INFINITY 同士の比較などの挙動が
676
+ 異なります。同梱のテストスクリプトはかなり網羅的ではあるものの、Ruby
677
+ の多数のバージョンでテストはしておりません。したがって、バージョンに
678
+ よっては、(極めて稀でしょうが)問題が発生する可能性が否定できません。
679
+ * {RangeExtd#hash} メソッドは、ある RangeExtdオブジェに対して常に唯一で排他的な
680
+ 数値を返すことが理論保証はされていません。ただし、現実的にそれが破られることは、まず
681
+ ありません。
682
+
683
+ パッケージに含まれている通り、網羅的なテストが実行されています。
684
+
685
+
686
+ == 開発項目
687
+
688
+ * Ruby 2.6の後ろに無限に開いたRange({Endless Range}[https://rubyreferences.github.io/rubychanges/2.6.html#endless-range-1])に対応する。
689
+
690
+
691
+ == 終わりに
692
+
693
+ RangeExtd内部に閉じた(Rangeでなく)挙動、たとえば RangeExtd同士の比較などは、
694
+ 全てユーザーにとって自然なもののはずです(と期待します?)。少なくとも、RangeExtdに
695
+ よってレンジの論理構造が完結した今、これはよく定義されかつ自己矛盾が無いものと言
696
+ えましょう。ただ、端の無限に開いた、あるいは始点が除外されたレンジの挙動には、
697
+ 一瞬ぎょっとするものが無くはないかも知れないことに注意して下さい。たとえば、
698
+ 片端が小さい方向に無限に開いて離散的な要素を持つレンジに対してメソッド
699
+ <tt>member?(obj)</tt> を実行すると、 <tt>nil</tt>が返ります。これは、無限(小)に
700
+ は実質的な意味を持つ <tt>succ()</tt> メソッドが定義されていないためで、したがっ
701
+ て与えられた objがレンジの要素(member)かどうかを調べることが、一般論としては理論
702
+ 的に不可能だからです。これはちょっと不思議に思うかも知れませんが、それはつまり定
703
+ 命の私たちには無限という概念を計り知るのが容易でない、というだけの話でしょう!
704
+
705
+ 一方、RangeExtd と Range との比較は、それ以上に驚くことがあるかも知れません。こ
706
+ れは、組込Rangeクラスで許容されているレンジの一部は、始点を除外することを認めた
707
+ 枠組の中では、前述のように最早有効(valid)と見なされないからです。この枠組に慣れるに
708
+ したがって、それらが自然だと思えるようになればいいのですが。保証しますが、一旦こ
709
+ れに慣れてしまえば、論理的不完全さ極まる混沌とした世界、つまりは Rangeの現在の挙
710
+ 動には二度と戻りたくなくなることでしょう!
711
+
712
+ お楽しみ下さい。
713
+
714
+
715
+ == その他
716
+
717
+ == 著作権他情報
718
+
719
+ 著者:: Masa Sakano < imagine a_t sakano dot co dot uk >
720
+ 利用許諾条項:: MIT.
721
+ 保証:: 一切無し。
722
+ バージョン:: Semantic Versioning (2.0.0) http://semver.org/
723
+