kyanite 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. data/0 start all Tests.bat +23 -0
  2. data/History.txt +4 -0
  3. data/License.txt +21 -0
  4. data/Manifest.txt +88 -0
  5. data/PostInstall.txt +4 -0
  6. data/README.txt +48 -0
  7. data/Rakefile.rb +79 -0
  8. data/init.rb +2 -0
  9. data/lib/kyanite.rb +39 -0
  10. data/lib/kyanite/array.rb +5 -0
  11. data/lib/kyanite/array/array.rb +172 -0
  12. data/lib/kyanite/array/array2.rb +140 -0
  13. data/lib/kyanite/array/matrix2.rb +120 -0
  14. data/lib/kyanite/array_of_enumerables.rb +2 -0
  15. data/lib/kyanite/array_of_numerics.rb +2 -0
  16. data/lib/kyanite/array_of_strings.rb +2 -0
  17. data/lib/kyanite/basics.rb +60 -0
  18. data/lib/kyanite/dictionary.rb +116 -0
  19. data/lib/kyanite/enumerable.rb +7 -0
  20. data/lib/kyanite/enumerable/enumerable_enumerables.rb +70 -0
  21. data/lib/kyanite/enumerable/enumerable_numerics.rb +171 -0
  22. data/lib/kyanite/enumerable/enumerable_strings.rb +58 -0
  23. data/lib/kyanite/enumerable/structure.rb +170 -0
  24. data/lib/kyanite/general.rb +8 -0
  25. data/lib/kyanite/general/callerutils.rb +128 -0
  26. data/lib/kyanite/general/classutils.rb +246 -0
  27. data/lib/kyanite/general/kernel.rb +105 -0
  28. data/lib/kyanite/general/nil.rb +64 -0
  29. data/lib/kyanite/general/object.rb +86 -0
  30. data/lib/kyanite/general/true_false.rb +65 -0
  31. data/lib/kyanite/general/undoable.rb +24 -0
  32. data/lib/kyanite/hash.rb +170 -0
  33. data/lib/kyanite/matrix2.rb +2 -0
  34. data/lib/kyanite/nil.rb +3 -0
  35. data/lib/kyanite/numeric.rb +4 -0
  36. data/lib/kyanite/numeric/float.rb +26 -0
  37. data/lib/kyanite/numeric/integer.rb +34 -0
  38. data/lib/kyanite/numeric/numeric.rb +45 -0
  39. data/lib/kyanite/operation.rb +5 -0
  40. data/lib/kyanite/operation/call_tracker.rb +69 -0
  41. data/lib/kyanite/operation/rake.rb +101 -0
  42. data/lib/kyanite/operation/regexp.rb +23 -0
  43. data/lib/kyanite/operation/unit_test.rb +53 -0
  44. data/lib/kyanite/optimizer.rb +119 -0
  45. data/lib/kyanite/rake.rb +2 -0
  46. data/lib/kyanite/range.rb +54 -0
  47. data/lib/kyanite/set.rb +219 -0
  48. data/lib/kyanite/smart_load_path.rb +2 -0
  49. data/lib/kyanite/string.rb +13 -0
  50. data/lib/kyanite/string/cast.rb +104 -0
  51. data/lib/kyanite/string/chars.rb +184 -0
  52. data/lib/kyanite/string/chars_const.rb +190 -0
  53. data/lib/kyanite/string/diff.rb +78 -0
  54. data/lib/kyanite/string/div.rb +19 -0
  55. data/lib/kyanite/string/include.rb +43 -0
  56. data/lib/kyanite/string/list.rb +84 -0
  57. data/lib/kyanite/string/mgsub.rb +35 -0
  58. data/lib/kyanite/string/nested.rb +253 -0
  59. data/lib/kyanite/string/random.rb +69 -0
  60. data/lib/kyanite/string/split.rb +136 -0
  61. data/lib/kyanite/symbol.rb +19 -0
  62. data/lib/kyanite/tree.rb +99 -0
  63. data/lib/kyanite/undoable.rb +2 -0
  64. data/lib/kyanite/unit_test.rb +2 -0
  65. data/test/_start_all.rb +17 -0
  66. data/test/array/test_array.rb +106 -0
  67. data/test/array/test_matrix2.rb +162 -0
  68. data/test/enumerable/test_enumerable_enumerables.rb +46 -0
  69. data/test/enumerable/test_enumerable_numerics.rb +93 -0
  70. data/test/enumerable/test_enumerable_strings.rb +22 -0
  71. data/test/enumerable/test_structure.rb +220 -0
  72. data/test/general/test_classutils.rb +45 -0
  73. data/test/general/test_nil.rb +44 -0
  74. data/test/general/test_object.rb +49 -0
  75. data/test/general/test_true_false.rb +28 -0
  76. data/test/numeric/test_numeric_integer.rb +28 -0
  77. data/test/string/test_cast.rb +108 -0
  78. data/test/string/test_chars.rb +255 -0
  79. data/test/string/test_diff.rb +95 -0
  80. data/test/string/test_list.rb +141 -0
  81. data/test/string/test_nested.rb +361 -0
  82. data/test/string/test_split.rb +187 -0
  83. data/test/test_dictionary.rb +128 -0
  84. data/test/test_hash.rb +59 -0
  85. data/test/test_optimizer.rb +150 -0
  86. data/test/test_range.rb +41 -0
  87. data/test/test_set.rb +210 -0
  88. data/test/test_tree.rb +94 -0
  89. metadata +217 -0
@@ -0,0 +1,253 @@
1
+
2
+ class String
3
+
4
+
5
+ # Gibt die passende gegenteilige Klammer zurück
6
+ # '('.anti -> ')'
7
+ # '{'.anti -> '}'
8
+ # ']'.anti -> '['
9
+ # '<hallo>'.anti -> '</hallo>'
10
+ # '</hallo>'.anti -> '<hallo>'
11
+ def anti
12
+ if self.size == 1
13
+ return self.tr('([{<)]}>',')]}>([{<')
14
+ else
15
+ if self =~ /<([^\/].*)>/
16
+ return "</#{$1}>"
17
+ elsif self =~ /<\/(.*)>/
18
+ return "<#{$1}>"
19
+ end
20
+ end
21
+ return self
22
+ end
23
+
24
+
25
+
26
+ # Findet das nächste zueinander passende Klammerpaar ab Position start.
27
+ # Liefert die Positionen der Klammern als Range.
28
+ # Bsp.: 'Hallo(welt)wort'.index_bracket -> 5..10
29
+ def index_bracket( pattern=nil, start=0, last_found = nil )
30
+ return nil if self.empty?
31
+ pattern = /[{<\[]/ unless pattern
32
+ # pattern = /['"({<(\[]/ unless pattern
33
+ debug = false
34
+ puts 'untersuche ' + self[start..-1] if debug
35
+ found = self.index(pattern, start)
36
+ puts "found=#{found}" if debug
37
+ return last_found unless found
38
+ pattern_anti = self[found..found].anti
39
+ startpunkt = found
40
+ loop do
41
+ found_next = self.index( pattern, startpunkt+1 ) || 9999999
42
+ found_anti = self.index( pattern_anti, startpunkt+1 )
43
+ puts "found_next=#{found_next}" if debug
44
+ puts "found_anti=#{found_anti}" if debug
45
+ break unless found_anti
46
+ return found..found_anti if found_anti <= found_next
47
+ # puts
48
+ # puts
49
+ # puts
50
+ # puts
51
+ # puts
52
+ # puts "start=#{(start).inspect_pp}"
53
+ # puts "pattern=#{(pattern).inspect_pp}"
54
+ # puts "found_next=#{(found_next).inspect_pp}"
55
+ # puts "found..found_anti=#{(found..found_anti).inspect_pp}"
56
+ rekursiv_result = self.index_bracket(pattern, found_next, found..found_anti)
57
+ return found..found_anti unless rekursiv_result
58
+ startpunkt = rekursiv_result.last
59
+ puts "startpunkt=#{startpunkt}" if debug
60
+ end # loop
61
+ nil
62
+ end
63
+
64
+
65
+ # Wendet den Block auf eine hierarchisch definierte Auswahl des Strings an.
66
+ # Beispiele siehe Tests.
67
+ def mask( options={}, &block )
68
+
69
+ # vorbereiten
70
+ debug = false
71
+ result = self.dup
72
+
73
+ level_start = options[:level_start] || 1
74
+ level_end = options[:level_end] || 99999
75
+ level_akt = options[:level_akt] || 0
76
+ #level_akt += 1 if with_brackets
77
+ pattern = options[:pattern] || /[{<\[]/ # /['"({<\[]/ ist langsam
78
+ skip_empty = options[:skip_empty] || false
79
+ param_level = options[:param_level] || false # übergibt dem Block zusätzlich die Nummer des aktuellen Levels
80
+ with_brackets = options[:with_brackets] || false # übergibt dem Block auch die Brackets, Beispiel siehe Tests!!
81
+
82
+ raise ArgumentError, "level_start can't be nil" unless level_start
83
+ raise ArgumentError, "level_end can't be nil" unless level_end
84
+ raise ArgumentError, 'level_end has to be >= level_start' unless level_end >= level_start
85
+ if debug
86
+ puts "level_start=#{level_start}"
87
+ puts "level_end=#{level_end}"
88
+ puts "level_akt=#{level_akt}"
89
+ puts
90
+ end
91
+ geklammert = result.index_bracket(pattern)
92
+ puts "geklammert=#{geklammert}" if debug
93
+
94
+
95
+ # Los geht's: geklammert, Klammern werden nicht mit übergeben
96
+ if geklammert
97
+ if !with_brackets
98
+ if geklammert.first > 0
99
+ pre = result[0..geklammert.first-1]
100
+ else
101
+ pre = ''
102
+ end
103
+ bra = result[geklammert.first..geklammert.first]
104
+ mid = result[geklammert.first+1..geklammert.last-1]
105
+ ket = result[geklammert.last..geklammert.last]
106
+ if geklammert.last < (result.size-1)
107
+ past = result[geklammert.last+1..-1]
108
+ else
109
+ past = ''
110
+ end
111
+ else # with_brackets
112
+ if geklammert.first > 0
113
+ pre = result[0..geklammert.first]
114
+ else
115
+ pre = result[geklammert.first..geklammert.first]
116
+ end
117
+ bra = ''
118
+ mid = result[geklammert.first+1..geklammert.last-1]
119
+ ket = ''
120
+ if geklammert.last < (result.size-1)
121
+ past = result[geklammert.last..-1]
122
+ else
123
+ past = result[geklammert.last..geklammert.last]
124
+ end
125
+ end
126
+ if debug
127
+ puts "1pre=#{pre}"
128
+ puts "1bra=#{bra}"
129
+ puts "1mid=#{mid}"
130
+ puts "1ket=#{ket}"
131
+ puts "1past=#{past}"
132
+ puts
133
+ end
134
+
135
+ # yield
136
+ if ( (level_start..level_end) === level_akt && (!pre.empty? || !skip_empty) )
137
+ if param_level
138
+ pre = yield(pre,level_akt)
139
+ else
140
+ pre = yield(pre)
141
+ end
142
+ end # if yield
143
+ mid = mid.mask( options.merge({:level_akt => level_akt+1}), &block )
144
+ past = past.mask( options, &block )
145
+ if debug
146
+ puts "2pre=#{pre}"
147
+ puts "2bra=#{bra}"
148
+ puts "2mid=#{mid}"
149
+ puts "2ket=#{ket}"
150
+ puts "2past=#{past}"
151
+ puts
152
+ end
153
+
154
+ return (pre||'') + bra + (mid||'') + ket + (past||'')
155
+
156
+
157
+
158
+ # Los geht's: keine Klammern
159
+ else
160
+ # yield
161
+
162
+ if ( (level_start..level_end) === level_akt && (!result.empty? || !skip_empty ) )
163
+
164
+ puts "result=#{result}\n" if debug
165
+ if param_level
166
+ result = yield(result,level_akt)
167
+ else
168
+ result= yield(result)
169
+ end
170
+ end # if yield
171
+ return (result||'')
172
+ end
173
+
174
+ raise 'no go'
175
+
176
+ end # def
177
+
178
+
179
+ # Liefert die Verschachtelungstiefe
180
+ def nestinglevel(pattern=/[{<(\[]/)
181
+ result = 0
182
+ self.mask( :level_start => 0,
183
+ :pattern => pattern,
184
+ :param_level => true ) { |s,l|
185
+ if l > result
186
+ result = l
187
+ s
188
+ else
189
+ s
190
+ end
191
+ }
192
+ result
193
+ end
194
+
195
+
196
+
197
+
198
+
199
+
200
+
201
+ end # class
202
+
203
+
204
+ class NilClass
205
+ def anti; nil; end
206
+ def index_bracket; nil; end
207
+ def mask(*a); nil; end
208
+ def nestinglevel; 0; end
209
+ end
210
+
211
+
212
+
213
+ # ------------------------------------------------------------------------------
214
+ # Tests
215
+ #
216
+
217
+
218
+ if $0 == __FILE__
219
+
220
+ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test', 'string', 'test_nested' )
221
+
222
+ end # if
223
+
224
+
225
+
226
+
227
+
228
+
229
+
230
+
231
+
232
+
233
+
234
+
235
+
236
+
237
+
238
+
239
+
240
+
241
+
242
+
243
+
244
+
245
+
246
+
247
+
248
+
249
+
250
+
251
+
252
+
253
+
@@ -0,0 +1,69 @@
1
+
2
+ unless defined? STRING_RANDOM_BASIS
3
+ string_random_basis = Hash.new
4
+ password = [('0'..'9'),('A'..'Z'),('a'..'z')].map {|range| range.to_a}.flatten
5
+ string_random_basis[:password] = password
6
+
7
+ de_hauf = [ [ 'ß', 3 ],
8
+ [ 'ä', 5 ],
9
+ [ 'ö', 3 ],
10
+ [ 'ü', 8 ],
11
+ [ 'a', 51 ],
12
+ [ 'b', 19 ],
13
+ [ 'c', 30 ],
14
+ [ 'd', 51 ],
15
+ [ 'e', 174 ],
16
+ [ 'f', 17 ],
17
+ [ 'g', 30 ],
18
+ [ 'h', 48 ],
19
+ [ 'i', 76 ],
20
+ [ 'j', 3 ],
21
+ [ 'k', 12 ],
22
+ [ 'l', 34 ],
23
+ [ 'm', 25 ],
24
+ [ 'n', 98 ],
25
+ [ 'o', 23 ],
26
+ [ 'p', 8 ],
27
+ [ 'q', 1 ],
28
+ [ 'r', 70 ],
29
+ [ 's', 72 ],
30
+ [ 't', 61 ],
31
+ [ 'u', 40 ],
32
+ [ 'v', 7 ],
33
+ [ 'w', 19 ],
34
+ [ 'x', 1 ],
35
+ [ 'y', 1 ],
36
+ [ 'z', 11 ]]
37
+ de_array = []
38
+ de_hauf.each do | buchstabe, haufigkeit |
39
+ de_array += [buchstabe]*haufigkeit
40
+ end
41
+ string_random_basis[:de] = de_array
42
+ STRING_RANDOM_BASIS = string_random_basis
43
+ end
44
+
45
+ class String
46
+
47
+ # Zufällige Reihenfolge
48
+ def shuffle(separator=//)
49
+ split(separator).shuffle.join('')
50
+ end
51
+
52
+ # In-place-Variante von shuffle
53
+ def shuffle!(separator=//)
54
+ self.replace( shuffle(separator) )
55
+ end
56
+
57
+
58
+ def String.random( type=:de, size=16)
59
+ (0...size).map { STRING_RANDOM_BASIS[type][Kernel.rand(STRING_RANDOM_BASIS[type].size)] }.join
60
+ end
61
+
62
+ end
63
+
64
+
65
+ class NilClass
66
+ def shuffle; nil; end
67
+ def shuffle!; nil; end
68
+ end
69
+
@@ -0,0 +1,136 @@
1
+
2
+
3
+ require 'facets/string/shatter'
4
+ require 'kyanite/string/cast'
5
+ require 'kyanite/enumerable'
6
+ require 'kyanite/array/array'
7
+
8
+
9
+ # ---------------------------------------------------------------------------------------------------------------------------------
10
+ # :section: Aufsplitten
11
+ #
12
+ # Aus {Facets/String}[http://facets.rubyforge.org/rdoc/Core/classes/String.html] eingefügt:
13
+ # * <tt>shatter(re)</tt> :: Breaks a string up into an array based on a regular expression. Similar to +scan+, but includes the matches.
14
+ #
15
+ class String
16
+
17
+
18
+ # Returns _n_ characters of the string. If _n_ is positive
19
+ # the characters are from the beginning of the string.
20
+ # If _n_ is negative from the end of the string.
21
+ #
22
+ # Alternatively a replacement string can be given, which will
23
+ # replace the _n_ characters.
24
+ # Example:
25
+ # 'abcde'.nchar(2) => 'ab'
26
+ # 'abcde'.nchar(2,'') => 'cde'
27
+ #
28
+ # NICHT die Version aus Facets verwenden!!!
29
+ # Tests siehe TestKyaniteStringSplit#test_nchar
30
+ def nchar(n, replacement=nil)
31
+ if replacement
32
+ return self if n == 0
33
+ return '' if (n.abs >= self.length)
34
+ s = self.dup
35
+ n > 0 ? (s[0...n] = replacement) : (s[n..-1] = replacement)
36
+ return s
37
+
38
+ # ohne replacement
39
+ else
40
+ return '' if n == 0
41
+ return self if (n.abs > self.length)
42
+ n > 0 ? self[0...n] : self[n..-1]
43
+ end
44
+ end
45
+
46
+
47
+ # Schneidet eine String auf eine Maximallänge. Bsp.:
48
+ # 'Hallo'.cut(3) => 'Hal'
49
+ #
50
+ # Tests siehe TestKyaniteStringSplit#test_cut
51
+ def cut(len=5)
52
+ return '' if len <= 0
53
+ self[0..len-1]
54
+ end
55
+
56
+
57
+ # Erzwingt eine bestimmte Länge
58
+ #
59
+ # Tests siehe TestKyaniteStringSplit#test_fixsize
60
+ def fixsize( len )
61
+ return '' if len <= 0
62
+ if self.size < len
63
+ self.ljust(len)
64
+ else
65
+ self[0..len-1]
66
+ end
67
+ end
68
+
69
+
70
+ # Schneidet einen String in Stücke.
71
+ # Wie lang die Stücke sind, sagt der Parameter (Format: einzelner Integer oder Array of Integer).
72
+ # Gibt alle Stücke zurück plus den Rest, der übrigbleibt.
73
+ #
74
+ # Beispiele & Tests siehe TestKyaniteStringSplit#test_split_by_index
75
+ def split_by_index(idx)
76
+ if idx.kind_of?(Integer)
77
+ [nchar(idx)] + [nchar(idx,'')]
78
+
79
+ elsif idx.kind_of?(Array)
80
+ [nchar(idx[0])] + nchar(idx[0],'').split_by_index(idx.shift_complement)
81
+
82
+ end # if
83
+ end
84
+
85
+
86
+
87
+ # Extrahiert einen Teilstring anhand zweier regulärer Ausdrücke. Beispiel:
88
+ # string = '<select id="hallo"><option value="0">none</option></select>'
89
+ # string.extract(/select.*?id="/,'"') => 'hallo'
90
+ #
91
+ def extract( start_regexp, stop_regexp )
92
+ split(start_regexp)[1].split(stop_regexp)[0]
93
+ end
94
+
95
+
96
+
97
+
98
+ # Trennt einen String in numerische und alphanumerische Teile auf.
99
+ # Funktioniert derzeit nur mit positiven Integers. Bsp.:
100
+ # 'abc123'.split_numeric >> ['abc',123] (Array)
101
+ # '123abc'.split_numeric >> [123,'abc'] (Array)
102
+ # '123'.split_numeric >> 123 (Integer)
103
+ # 'abc'.split_numeric >> 'abc' (String)
104
+ #
105
+ # Das funktioniert sogar mit mehr als zwei Teilen:
106
+ # '123abc456'.split_numeric >> [123,'abc',456]
107
+ # 'abc123def'.split_numeric >> ['abc',123,'def']
108
+ #
109
+ # Tests siehe TestKyaniteStringSplit#test_split_numeric
110
+ def split_numeric
111
+ result = shatter(/\d+/).collect{ |i| i.to_integer_optional }
112
+ return result[0] if ( result.is_collection? && result.size == 1 )
113
+ return result
114
+ end
115
+
116
+
117
+ # Trennt numerische Teile ab und entfernt abschließende Whitespaces, Bindestriche, Unterstriche und Punkte.
118
+ # Wird z.B. für die Generierung des Doku-Pfades verwendet.
119
+ #
120
+ # Tests siehe TestKyaniteStringClear
121
+ def without_versioninfo
122
+ shatter(/\d+/)[0].strip.chomp('_').chomp('-').chomp('.')
123
+ end
124
+
125
+ end
126
+
127
+
128
+ class NilClass
129
+ def nchar(*a); nil; end
130
+ def cut(*a); ''; end
131
+ def split_by_index(*a); nil; end
132
+ def extract(*a); nil; end
133
+ def split_numeric; nil; end
134
+ def without_versioninfo; nil; end
135
+ end
136
+