quality_extensions 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/Readme +54 -0
  2. data/lib/qualitysmith_extensions/all.rb +4 -0
  3. data/lib/qualitysmith_extensions/array/all.rb +2 -0
  4. data/lib/qualitysmith_extensions/array/average.rb +44 -0
  5. data/lib/qualitysmith_extensions/array/classify.rb +97 -0
  6. data/lib/qualitysmith_extensions/array/expand_ranges.rb +52 -0
  7. data/lib/qualitysmith_extensions/array/group_by.rb +134 -0
  8. data/lib/qualitysmith_extensions/array/sequence.rb +66 -0
  9. data/lib/qualitysmith_extensions/array/shell_escape.rb +36 -0
  10. data/lib/qualitysmith_extensions/array/to_a_recursive.rb +41 -0
  11. data/lib/qualitysmith_extensions/array/to_query_string.rb +96 -0
  12. data/lib/qualitysmith_extensions/collection_extensions_for_cgi.rb +2 -0
  13. data/lib/qualitysmith_extensions/colored/toggleability.rb +62 -0
  14. data/lib/qualitysmith_extensions/console/command.facets.1.8.51.rb +749 -0
  15. data/lib/qualitysmith_extensions/console/command.facets.1.8.54.rb +748 -0
  16. data/lib/qualitysmith_extensions/console/command.rb +944 -0
  17. data/lib/qualitysmith_extensions/date/all.rb +2 -0
  18. data/lib/qualitysmith_extensions/date/deprecated.rb +40 -0
  19. data/lib/qualitysmith_extensions/date/iso8601.rb +31 -0
  20. data/lib/qualitysmith_extensions/date/month_ranges.rb +122 -0
  21. data/lib/qualitysmith_extensions/dir/each_child.rb +58 -0
  22. data/lib/qualitysmith_extensions/enumerable/enum.rb +69 -0
  23. data/lib/qualitysmith_extensions/enumerable/select_until.rb +4 -0
  24. data/lib/qualitysmith_extensions/enumerable/select_while.rb +109 -0
  25. data/lib/qualitysmith_extensions/exception/inspect_with_backtrace.rb +65 -0
  26. data/lib/qualitysmith_extensions/file/exact_match_regexp.rb +34 -0
  27. data/lib/qualitysmith_extensions/file_test/binary_file.rb +110 -0
  28. data/lib/qualitysmith_extensions/find/select.rb +68 -0
  29. data/lib/qualitysmith_extensions/global_variable_set.rb +153 -0
  30. data/lib/qualitysmith_extensions/hash/all.rb +2 -0
  31. data/lib/qualitysmith_extensions/hash/to_date.rb +34 -0
  32. data/lib/qualitysmith_extensions/hash/to_query_string.rb +121 -0
  33. data/lib/qualitysmith_extensions/kernel/all.rb +2 -0
  34. data/lib/qualitysmith_extensions/kernel/autoreload.rb +128 -0
  35. data/lib/qualitysmith_extensions/kernel/backtrace.rb +71 -0
  36. data/lib/qualitysmith_extensions/kernel/capture_output.rb +115 -0
  37. data/lib/qualitysmith_extensions/kernel/die.rb +49 -0
  38. data/lib/qualitysmith_extensions/kernel/example_printer.rb +81 -0
  39. data/lib/qualitysmith_extensions/kernel/filter_output.rb +108 -0
  40. data/lib/qualitysmith_extensions/kernel/remove_const.rb +178 -0
  41. data/lib/qualitysmith_extensions/kernel/remove_module.rb +127 -0
  42. data/lib/qualitysmith_extensions/kernel/require_all.rb +186 -0
  43. data/lib/qualitysmith_extensions/kernel/require_local_all.rb +4 -0
  44. data/lib/qualitysmith_extensions/kernel/require_once.rb +18 -0
  45. data/lib/qualitysmith_extensions/kernel/simulate_input.rb +52 -0
  46. data/lib/qualitysmith_extensions/kernel/trap_chain.rb +61 -0
  47. data/lib/qualitysmith_extensions/kernel/windows_platform.rb +46 -0
  48. data/lib/qualitysmith_extensions/module/alias_method.rb +6 -0
  49. data/lib/qualitysmith_extensions/module/alias_method_chain.rb +165 -0
  50. data/lib/qualitysmith_extensions/module/ancestry_of_instance_method.rb +43 -0
  51. data/lib/qualitysmith_extensions/module/attribute_accessors.rb +49 -0
  52. data/lib/qualitysmith_extensions/module/basename.rb +76 -0
  53. data/lib/qualitysmith_extensions/module/bool_attr_accessor.rb +497 -0
  54. data/lib/qualitysmith_extensions/module/class_methods.rb +87 -0
  55. data/lib/qualitysmith_extensions/module/create.rb +315 -0
  56. data/lib/qualitysmith_extensions/module/create_setter.rb +9 -0
  57. data/lib/qualitysmith_extensions/module/dirname.rb +4 -0
  58. data/lib/qualitysmith_extensions/module/guard_method.rb +312 -0
  59. data/lib/qualitysmith_extensions/module/includable_once.rb +10 -0
  60. data/lib/qualitysmith_extensions/module/join.rb +66 -0
  61. data/lib/qualitysmith_extensions/module/malias_method_chain.rb +92 -0
  62. data/lib/qualitysmith_extensions/module/module_methods.rb +4 -0
  63. data/lib/qualitysmith_extensions/module/namespace.rb +112 -0
  64. data/lib/qualitysmith_extensions/module/parents.rb +61 -0
  65. data/lib/qualitysmith_extensions/module/remove_const.rb +117 -0
  66. data/lib/qualitysmith_extensions/module/split.rb +55 -0
  67. data/lib/qualitysmith_extensions/month.rb +66 -0
  68. data/lib/qualitysmith_extensions/mutex/if_available.rb +75 -0
  69. data/lib/qualitysmith_extensions/object/ancestry_of_method.rb +257 -0
  70. data/lib/qualitysmith_extensions/object/default.rb +69 -0
  71. data/lib/qualitysmith_extensions/object/if_else.rb +157 -0
  72. data/lib/qualitysmith_extensions/object/ignore_access.rb +84 -0
  73. data/lib/qualitysmith_extensions/object/mcall.rb +92 -0
  74. data/lib/qualitysmith_extensions/object/methods.rb +63 -0
  75. data/lib/qualitysmith_extensions/object/send_if.rb +151 -0
  76. data/lib/qualitysmith_extensions/object/send_if_not_nil.rb +35 -0
  77. data/lib/qualitysmith_extensions/object/singleton_send.rb +129 -0
  78. data/lib/qualitysmith_extensions/regexp/join.rb +111 -0
  79. data/lib/qualitysmith_extensions/string/all.rb +2 -0
  80. data/lib/qualitysmith_extensions/string/constantize.rb +4 -0
  81. data/lib/qualitysmith_extensions/string/digits_only.rb +27 -0
  82. data/lib/qualitysmith_extensions/string/each_char_with_index.rb +41 -0
  83. data/lib/qualitysmith_extensions/string/md5.rb +29 -0
  84. data/lib/qualitysmith_extensions/string/shell_escape.rb +43 -0
  85. data/lib/qualitysmith_extensions/string/to_underscored_label.rb +37 -0
  86. data/lib/qualitysmith_extensions/string/with_knowledge_of_color.rb +64 -0
  87. data/lib/qualitysmith_extensions/symbol/constantize.rb +69 -0
  88. data/lib/qualitysmith_extensions/symbol/match.rb +157 -0
  89. data/lib/qualitysmith_extensions/template.rb +33 -0
  90. data/lib/qualitysmith_extensions/test/all.rb +2 -0
  91. data/lib/qualitysmith_extensions/test/assert_anything.rb +93 -0
  92. data/lib/qualitysmith_extensions/test/assert_changed.rb +66 -0
  93. data/lib/qualitysmith_extensions/test/assert_exception.rb +66 -0
  94. data/lib/qualitysmith_extensions/test/assert_includes.rb +36 -0
  95. data/lib/qualitysmith_extensions/test/assert_user_error.rb +37 -0
  96. data/lib/qualitysmith_extensions/test/difference_highlighting.rb +323 -0
  97. data/lib/qualitysmith_extensions/time/all.rb +2 -0
  98. data/lib/qualitysmith_extensions/time/deprecated.rb +31 -0
  99. data/test/all.rb +16 -0
  100. metadata +148 -0
data/Readme ADDED
@@ -0,0 +1,54 @@
1
+ = QualitySmith Extensions
2
+
3
+ [<b>Home page</b>:] http://qualitysmithext.rubyforge.org/
4
+ [<b>Project site</b>:] http://rubyforge.org/projects/qualitysmithext/
5
+ [<b>Gem install</b>:] <tt>gem install qualitysmith_extensions</tt>
6
+ [<b>License</b>:] {Ruby License}[link:files/License.html]
7
+
8
+ == Introduction
9
+
10
+ This is a library of miscellaneous general-purpose, reusable Ruby code, quite similar in purpose and layout to {Ruby Facets}[http://facets.rubyforge.org/]. It is certainly not meant to _compete_ with Facets though!
11
+
12
+ Developers are encouraged to first check if the method or class they are looking for already exists in one of the fine existing open-source projects (like {Facets}[http://facets.rubyforge.org/] or {Extensions}[http://extensions.rubyforge.org/rdoc/index.html] or {stdlib}[http://www.ruby-doc.org/stdlib/]).
13
+
14
+ If the code you are needing hasn't already been written by someone else, then you can throw it in this library. Also submit it to an existing extensions project if you think it's any good.
15
+
16
+ Like Facets, this library contains:
17
+ * methods that add functionality to existing Ruby classes (String, Array, etc.)
18
+ * as well as new classes that aren't in core Ruby
19
+
20
+ == Installation
21
+
22
+ gem install qualitysmith_extensions
23
+
24
+ == Usage
25
+
26
+ require 'rubygems'
27
+ gem 'qualitysmith_extensions'
28
+
29
+ And then <b>include as much or as little as you want</b>.
30
+
31
+ Use the handy <tt>all.rb</tt> files to load everything in a particular directory (and all subdirectories).
32
+
33
+ To load everything:
34
+
35
+ require 'qualitysmith_extensions/all'
36
+
37
+ To load everything just for one class:
38
+
39
+ require 'qualitysmith_extensions/string/all'
40
+
41
+ To load just an individual method:
42
+
43
+ require 'qualitysmith_extensions/array/average'
44
+
45
+
46
+ == Running tests
47
+
48
+ Tests are self-contained within the file for the code that is under test.
49
+
50
+ To run the tests directly, you need to use the <tt>exrb</tt> command that is part of the {Ratchets}[http://ratchets.rubyforge.org/] project.
51
+
52
+ At some point in time, we may extract them into separate files using the Exacto test extractor tool.
53
+
54
+ <b>QualitySmith developers</b>: If you use <tt>vim</tt>, you can set up your editor to run the tests just by typing the <tt>:Test</tt> command. To set that up, just include <tt>~/svn/devscripts/vim/include.vim</tt> .
@@ -0,0 +1,4 @@
1
+ require File.dirname(__FILE__) + "/kernel/require_all"
2
+ require_all File.dirname(__FILE__),
3
+ :exclude => /(^|\/)test\//, # Don't include anything in test/ because those files will include test/unit, which causes tests to automatically be run (an unfortunate side-effect)!
4
+ :exclude_files => 'all.rb'
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + "/../kernel/require_all"
2
+ require_all File.dirname(__FILE__), :exclude_files => 'all.rb'
@@ -0,0 +1,44 @@
1
+ #--
2
+ # Author:: Tyler Rick
3
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
4
+ # License:: Ruby License
5
+ # Submit to Facets?:: Yes.
6
+ # Wait, so Facets has mode (http://facets.rubyforge.org/src/doc/rdoc/core/classes/Enumerable.html#M001253) but it doesn't have mean/average?
7
+ # Whether or not this Array#average is included, Facets ought to have an Enumerable#mean/average similar to mode that uses each iterator rather than Array#size. (Still might want to keep this version if it's more efficient for Arrays?)
8
+ #++
9
+
10
+ class Array
11
+ # Calculates the arithmetic average (mean) of the elements in the array as a <tt>Float</tt>.
12
+ # irb -> [1, 3, 3].average
13
+ # => 2.33333333333333
14
+ def average
15
+ if self.size == 0
16
+ raise ZeroDivisionError
17
+ end
18
+ self.inject(0.0) do |sum, item|
19
+ sum + item.to_f
20
+ end / self.size
21
+ end
22
+ end
23
+
24
+ # _____ _
25
+ # |_ _|__ ___| |_
26
+ # | |/ _ \/ __| __|
27
+ # | | __/\__ \ |_
28
+ # |_|\___||___/\__|
29
+ #
30
+ =begin test
31
+ require 'test/unit'
32
+ class TheTest < Test::Unit::TestCase
33
+ def test_average
34
+ assert_equal 2, [0, 4].average
35
+ assert_equal Float, [0, 4].average.class
36
+
37
+ assert_equal 2.5, [0, 5].average
38
+
39
+ assert_raise ZeroDivisionError do
40
+ [].average
41
+ end
42
+ end
43
+ end
44
+ =end
@@ -0,0 +1,97 @@
1
+ #--
2
+ # Author:: Tyler Rick
3
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
4
+ # License:: Ruby License
5
+ # Submit to Facets?:: Yes!
6
+ # Developer notes:
7
+ # * This is the analog in Array to Set#classify (core).
8
+ # * Compare to Array#group_by (qualitysmith_extensions), which assumes all elements are arrays (making a "table") and only
9
+ # allows you to do simple classification by the value of a "column". On the other hand, it adds the option to delete that
10
+ # column from the array, which can be nice, since the classification key in the hash makes it somewhat redundant.
11
+ #++
12
+
13
+ require 'rubygems'
14
+ gem 'facets'
15
+ require 'facet/array/to_hash'
16
+ class Array
17
+
18
+ =begin rdoc
19
+ Classifies the array by the return value of the given block and returns a hash of {value => array of elements} pairs.
20
+ The block is called once for each element of the array, passing the element as parameter.
21
+
22
+ Breaks an array into a hash of smaller arrays, making a new group for each unique value returned by the block. Each unique value becomes a key in the hash.
23
+
24
+ Example:
25
+ [
26
+ ['a', 1],
27
+ ['a', 2],
28
+ ['b', 3],
29
+ ['b', 4],
30
+ ].classify {|o| o[0]}
31
+ =>
32
+ {
33
+ "a" => [['a', 1], ['a', 2]],
34
+ "b" => [['b', 3], ['b', 4]]
35
+ }
36
+ =end
37
+ def classify(&block)
38
+ hash = {}
39
+ each do |element|
40
+ classification = yield(element)
41
+ (hash[classification] ||= []) << element
42
+ end
43
+ hash
44
+ end
45
+ end
46
+
47
+ # _____ _
48
+ # |_ _|__ ___| |_
49
+ # | |/ _ \/ __| __|
50
+ # | | __/\__ \ |_
51
+ # |_|\___||___/\__|
52
+ #
53
+ =begin test
54
+ require 'set'
55
+
56
+ class TheTest < Test::Unit::TestCase
57
+ def test_classify
58
+ input = [
59
+ ['a', 1],
60
+ ['a', 2],
61
+ ['b', 3],
62
+ ['b', 4],
63
+ ]
64
+ assert_equal({
65
+ "a" => [['a', 1], ['a', 2]],
66
+ "b" => [['b', 3], ['b', 4]]
67
+ }, input.classify {|o| o[0]}
68
+ )
69
+ # For comparison:
70
+ assert_equal({
71
+ "a" => Set[['a', 1], ['a', 2]],
72
+ "b" => Set[['b', 3], ['b', 4]]
73
+ }, input.to_set.classify {|o| o[0]}
74
+ )
75
+
76
+
77
+ input = [
78
+ ['Bob', "Bottle of water", 1.00],
79
+ ['Bob', "Expensive stapler", 50.00],
80
+ ['Alice', "Dinner for 2", 100.00],
81
+ ['Alice', "Bus ride to RubyConf", 50.00],
82
+ ]
83
+ assert_equal({
84
+ "Alice" => [['Alice',"Dinner for 2", 100.0], ['Alice', "Bus ride to RubyConf", 50.0]],
85
+ "Bob" => [['Bob', "Bottle of water", 1.0], ['Bob', "Expensive stapler", 50.0]]
86
+ }, input.classify {|o| o[0]}
87
+ )
88
+ assert_equal({
89
+ 50.0 => [["Bob", "Expensive stapler", 50.00], ["Alice", "Bus ride to RubyConf", 50.00]],
90
+ 100.0 => [["Alice", "Dinner for 2", 100.00]],
91
+ 1.0 => [["Bob", "Bottle of water", 1.00]]
92
+ }, input.classify {|o| o[2]}
93
+ )
94
+ end
95
+ end
96
+ =end
97
+
@@ -0,0 +1,52 @@
1
+ #--
2
+ # Author:: Tyler Rick
3
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
4
+ # License:: Ruby License
5
+ # Submit to Facets?:: Yes.
6
+ #++
7
+
8
+ require 'rubygems'
9
+ require 'facets/core/kernel/silence_warnings'
10
+
11
+ class Array
12
+ # Expands (calls +to_a+ on) all Ranges contained in this array, replacing the range with the list of *elements* that the range represents.
13
+ #
14
+ # This is especially useful when you want to have "discontiguous ranges" like [1..3, 5..7]...
15
+ #
16
+ # [1..3, 5..7].expand_ranges
17
+ # => [1, 2, 3, 5, 6, 7]
18
+ #
19
+ def expand_ranges
20
+ new_array = []
21
+ each do |item|
22
+ silence_warnings do # Object.to_a: warning: default `to_a' will be obsolete
23
+ if item.respond_to?(:to_a)
24
+ new_array.concat item.to_a
25
+ else
26
+ new_array.concat [item]
27
+ end
28
+ end
29
+ end
30
+ new_array
31
+ end
32
+ end
33
+
34
+ # _____ _
35
+ # |_ _|__ ___| |_
36
+ # | |/ _ \/ __| __|
37
+ # | | __/\__ \ |_
38
+ # |_|\___||___/\__|
39
+ #
40
+ =begin test
41
+ require 'test/unit'
42
+ class TheTest < Test::Unit::TestCase
43
+ def test_1
44
+ assert_equal [1, 2, 3], [1, 2, 3].expand_ranges
45
+ end
46
+ def test_2
47
+ assert_equal [1, 2, 3], [1..3].expand_ranges
48
+ assert_equal [1, 2, 3, 5, 6, 7], [1..3, 5..7].expand_ranges
49
+ end
50
+ end
51
+ =end
52
+
@@ -0,0 +1,134 @@
1
+ #--
2
+ # Author:: Tyler Rick
3
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
4
+ # License:: Ruby License
5
+ # Submit to Facets?:: Maybe.
6
+ # Developer notes:
7
+ # * Name is too general? Name it something to do with 'tables'?
8
+ # * group_table_by ?
9
+ # * Compare to Array#classify (qualitysmith_extensions), which aims to be more general, letting you classify arrays that are
10
+ # *not* in "table" form (whose elements are *not* all arrays of equal size and might not even be *arrays*).
11
+ #++
12
+
13
+ require 'rubygems'
14
+ gem 'facets'
15
+ require 'facet/array/delete_values_at'
16
+ class Array
17
+
18
+ =begin rdoc
19
+ Breaks an array into a hash of smaller arrays, making a new group for each unique value in the specified column.
20
+ Each unique value becomes a key in the hash.
21
+
22
+ Example:
23
+ [
24
+ ['a', 1],
25
+ ['a', 2],
26
+ ['b', 3],
27
+ ['b', 4],
28
+ ].group_by(0)
29
+ =>
30
+ "a"=>[[1], [2]],
31
+ "b"=>[[3], [4]]
32
+
33
+ Options:
34
+ * <tt>delete_key</tt>: deletes the key from the corresponding array if true (default true)
35
+
36
+ Example:
37
+ [
38
+ ['a', 1],
39
+ ['a', 2],
40
+ ['b', 3],
41
+ ['b', 4],
42
+ ].group_by(0, :delete_key => false)
43
+ =>
44
+ "a"=>[['a', 1], ['a', 2]],
45
+ "b"=>[['b', 3], ['b', 4]]
46
+
47
+ *Notes*:
48
+ * <tt>self</tt> must be in the shape of a "table" (that is, a rectangular-shaped, two-dimensional array = an array of arrays,
49
+ each member array being of the same size (the "width" of the table)).
50
+ * This is different from the GROUP BY in SQL in that it doesn't apply an aggregate (like sum or average) to each group -- it just returns each group unmodified.
51
+
52
+ =end
53
+ def group_by(column_index, *args)
54
+ options = (if args.last.is_a?(Hash) then args.pop else {} end)
55
+ hash = {}
56
+ self.each do |row|
57
+ row_to_keep = row.dup
58
+ row_to_keep.delete_values_at(column_index) unless options[:delete_key] == false
59
+
60
+ hash[row[column_index]] ||= []
61
+ hash[row[column_index]] << row_to_keep
62
+ end
63
+ hash
64
+ end
65
+ end
66
+
67
+ # _____ _
68
+ # |_ _|__ ___| |_
69
+ # | |/ _ \/ __| __|
70
+ # | | __/\__ \ |_
71
+ # |_|\___||___/\__|
72
+ #
73
+ =begin test
74
+ require 'set'
75
+
76
+ class TheTest < Test::Unit::TestCase
77
+ def test_group_by
78
+ assert_equal({ }, [ ].group_by(column_index = 0))
79
+
80
+ assert_equal({
81
+ "a"=>[[1], [2]],
82
+ "b"=>[[3], [4]]
83
+ }, [
84
+ ['a', 1],
85
+ ['a', 2],
86
+ ['b', 3],
87
+ ['b', 4],
88
+ ].group_by(column_index = 0)
89
+ )
90
+
91
+
92
+
93
+ assert_equal({
94
+ "a"=>[['a', 1], ['a', 2]],
95
+ "b"=>[['b', 3], ['b', 4]]
96
+ }, [
97
+ ['a', 1],
98
+ ['a', 2],
99
+ ['b', 3],
100
+ ['b', 4],
101
+ ].group_by(column_index = 0, :delete_key => false)
102
+ )
103
+ assert_equal({
104
+ "a" => Set[['a', 1], ['a', 2]],
105
+ "b" => Set[['b', 3], ['b', 4]]
106
+ }, [
107
+ ['a', 1],
108
+ ['a', 2],
109
+ ['b', 3],
110
+ ['b', 4],
111
+ ].to_set.classify {|o| o[0]}
112
+ )
113
+
114
+
115
+ input = [
116
+ ['Bob', "Bottle of water", 1.00],
117
+ ['Bob', "Expensive stapler", 50.00],
118
+ ['Alice', "Dinner for 2", 100.00],
119
+ ['Alice', "Bus ride to RubyConf", 50.00],
120
+ ]
121
+ assert_equal({
122
+ "Alice"=>[["Dinner for 2", 100.0], ["Bus ride to RubyConf", 50.0]],
123
+ "Bob"=>[["Bottle of water", 1.0], ["Expensive stapler", 50.0]]
124
+ }, input.group_by(column_index = 0)
125
+ )
126
+ assert_equal({
127
+ 50.0=>[["Bob", "Expensive stapler"], ["Alice", "Bus ride to RubyConf"]],
128
+ 100.0=>[["Alice", "Dinner for 2"]],
129
+ 1.0=>[["Bob", "Bottle of water"]]
130
+ }, input.group_by(column_index = 2)
131
+ )
132
+ end
133
+ end
134
+ =end
@@ -0,0 +1,66 @@
1
+ #--
2
+ # Author:: Lance Ivy
3
+ # Copyright:: Copyright (c) 2007 QualitySmith, Inc.
4
+ # License:: Ruby License
5
+ # Submit to Facets?:: Not sure.
6
+ #++
7
+
8
+ class Array
9
+ =begin rdoc
10
+ Returns the value previous to the given value. The value previous to the first is the last. Returns nil if the given value is not in the array.
11
+
12
+ Example:
13
+ sequence = ['a', 'b', 'c']
14
+ sequence.before('a') => 'c'
15
+ sequence.before('b') => 'a'
16
+ sequence.before('c') => 'b'
17
+ sequence.before('d') => nil
18
+ =end
19
+ def before(value)
20
+ return nil unless include? value
21
+ self[(index(value).to_i - 1) % length]
22
+ end
23
+
24
+ =begin rdoc
25
+ Returns the value after the given value. The value before the last is the first. Returns nil if the given value is not in the array.
26
+
27
+ Example:
28
+ sequence = ['a', 'b', 'c']
29
+ sequence.after('a') => 'b'
30
+ sequence.after('b') => 'c'
31
+ sequence.after('c') => 'a'
32
+ sequence.after('d') => nil
33
+ =end
34
+ def after(value)
35
+ return nil unless include? value
36
+ self[(index(value).to_i + 1) % length]
37
+ end
38
+ end
39
+
40
+ # _____ _
41
+ # |_ _|__ ___| |_
42
+ # | |/ _ \/ __| __|
43
+ # | | __/\__ \ |_
44
+ # |_|\___||___/\__|
45
+ #
46
+ =begin test
47
+ class TheTest < Test::Unit::TestCase
48
+ def setup
49
+ @sequence = ['a', 'b', 'c']
50
+ end
51
+
52
+ def test_before
53
+ assert_equal 'c', @sequence.before('a')
54
+ assert_equal 'a', @sequence.before('b')
55
+ assert_equal 'b', @sequence.before('c')
56
+ assert_equal nil, @sequence.before('d')
57
+ end
58
+
59
+ def test_after
60
+ assert_equal 'b', @sequence.after('a')
61
+ assert_equal 'c', @sequence.after('b')
62
+ assert_equal 'a', @sequence.after('c')
63
+ assert_equal nil, @sequence.after('d')
64
+ end
65
+ end
66
+ =end