kyanite 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/0 start all Tests.bat +23 -0
- data/History.txt +4 -0
- data/License.txt +21 -0
- data/Manifest.txt +88 -0
- data/PostInstall.txt +4 -0
- data/README.txt +48 -0
- data/Rakefile.rb +79 -0
- data/init.rb +2 -0
- data/lib/kyanite.rb +39 -0
- data/lib/kyanite/array.rb +5 -0
- data/lib/kyanite/array/array.rb +172 -0
- data/lib/kyanite/array/array2.rb +140 -0
- data/lib/kyanite/array/matrix2.rb +120 -0
- data/lib/kyanite/array_of_enumerables.rb +2 -0
- data/lib/kyanite/array_of_numerics.rb +2 -0
- data/lib/kyanite/array_of_strings.rb +2 -0
- data/lib/kyanite/basics.rb +60 -0
- data/lib/kyanite/dictionary.rb +116 -0
- data/lib/kyanite/enumerable.rb +7 -0
- data/lib/kyanite/enumerable/enumerable_enumerables.rb +70 -0
- data/lib/kyanite/enumerable/enumerable_numerics.rb +171 -0
- data/lib/kyanite/enumerable/enumerable_strings.rb +58 -0
- data/lib/kyanite/enumerable/structure.rb +170 -0
- data/lib/kyanite/general.rb +8 -0
- data/lib/kyanite/general/callerutils.rb +128 -0
- data/lib/kyanite/general/classutils.rb +246 -0
- data/lib/kyanite/general/kernel.rb +105 -0
- data/lib/kyanite/general/nil.rb +64 -0
- data/lib/kyanite/general/object.rb +86 -0
- data/lib/kyanite/general/true_false.rb +65 -0
- data/lib/kyanite/general/undoable.rb +24 -0
- data/lib/kyanite/hash.rb +170 -0
- data/lib/kyanite/matrix2.rb +2 -0
- data/lib/kyanite/nil.rb +3 -0
- data/lib/kyanite/numeric.rb +4 -0
- data/lib/kyanite/numeric/float.rb +26 -0
- data/lib/kyanite/numeric/integer.rb +34 -0
- data/lib/kyanite/numeric/numeric.rb +45 -0
- data/lib/kyanite/operation.rb +5 -0
- data/lib/kyanite/operation/call_tracker.rb +69 -0
- data/lib/kyanite/operation/rake.rb +101 -0
- data/lib/kyanite/operation/regexp.rb +23 -0
- data/lib/kyanite/operation/unit_test.rb +53 -0
- data/lib/kyanite/optimizer.rb +119 -0
- data/lib/kyanite/rake.rb +2 -0
- data/lib/kyanite/range.rb +54 -0
- data/lib/kyanite/set.rb +219 -0
- data/lib/kyanite/smart_load_path.rb +2 -0
- data/lib/kyanite/string.rb +13 -0
- data/lib/kyanite/string/cast.rb +104 -0
- data/lib/kyanite/string/chars.rb +184 -0
- data/lib/kyanite/string/chars_const.rb +190 -0
- data/lib/kyanite/string/diff.rb +78 -0
- data/lib/kyanite/string/div.rb +19 -0
- data/lib/kyanite/string/include.rb +43 -0
- data/lib/kyanite/string/list.rb +84 -0
- data/lib/kyanite/string/mgsub.rb +35 -0
- data/lib/kyanite/string/nested.rb +253 -0
- data/lib/kyanite/string/random.rb +69 -0
- data/lib/kyanite/string/split.rb +136 -0
- data/lib/kyanite/symbol.rb +19 -0
- data/lib/kyanite/tree.rb +99 -0
- data/lib/kyanite/undoable.rb +2 -0
- data/lib/kyanite/unit_test.rb +2 -0
- data/test/_start_all.rb +17 -0
- data/test/array/test_array.rb +106 -0
- data/test/array/test_matrix2.rb +162 -0
- data/test/enumerable/test_enumerable_enumerables.rb +46 -0
- data/test/enumerable/test_enumerable_numerics.rb +93 -0
- data/test/enumerable/test_enumerable_strings.rb +22 -0
- data/test/enumerable/test_structure.rb +220 -0
- data/test/general/test_classutils.rb +45 -0
- data/test/general/test_nil.rb +44 -0
- data/test/general/test_object.rb +49 -0
- data/test/general/test_true_false.rb +28 -0
- data/test/numeric/test_numeric_integer.rb +28 -0
- data/test/string/test_cast.rb +108 -0
- data/test/string/test_chars.rb +255 -0
- data/test/string/test_diff.rb +95 -0
- data/test/string/test_list.rb +141 -0
- data/test/string/test_nested.rb +361 -0
- data/test/string/test_split.rb +187 -0
- data/test/test_dictionary.rb +128 -0
- data/test/test_hash.rb +59 -0
- data/test/test_optimizer.rb +150 -0
- data/test/test_range.rb +41 -0
- data/test/test_set.rb +210 -0
- data/test/test_tree.rb +94 -0
- 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
|
+
|