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.
- 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
|
+
|