friendly_extensions 0.0.61 → 0.0.62

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,220 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # Numeric Extensions
3
+ module Numbers
4
+
5
+ <<<<<<< HEAD
6
+ =======
7
+ # returns an array with all prime numbers up to limit
8
+ def self.prime_numbers(limit = 1_000_000, options = {:verbose => false})
9
+ i = 1; divisors = [2]; primzahlen = []
10
+ t = Time.now
11
+ while i <= limit do
12
+ p = true
13
+ divisors.each do |d|
14
+ if i%d == 0 && d != i
15
+ p = false
16
+ break
17
+ end
18
+ end
19
+
20
+ if p == true
21
+ puts i if options[:verbose] == true
22
+ primzahlen << i
23
+ end
24
+
25
+ i += 1
26
+ divisors << divisors.last+1
27
+ end
28
+
29
+ puts "Took #{(t-Time.now).abs.round(2)} sec." if options[:verbose] == true
30
+ return primzahlen
31
+ end
32
+
33
+ >>>>>>> ad58e345c5de2638e34e44d69bb19b0ebebcd41e
34
+ Numeric.class_eval do
35
+
36
+ # Convert Number to numeric german style with precision
37
+ def to_euro(label = nil, options = {})
38
+ options[:precision] ||= 2
39
+ result = ActionController::Base.helpers.number_with_precision(self, :precision => options[:precision], :separator => ",", :delimiter => ".")
40
+
41
+ if options[:pre] == true && self > 0
42
+ result = "+#{result}"
43
+ elsif options[:pre] == true && self < 0
44
+ result = "-#{result}"
45
+ end
46
+
47
+
48
+ if !label.blank?
49
+ return [result, label].join("&nbsp;").html_safe
50
+ else
51
+ return result
52
+ end
53
+ end
54
+
55
+ # Convert Number to numeric german style without precision
56
+ def to_de(label=nil)
57
+ <<<<<<< HEAD
58
+ =======
59
+ nr = self.round.to_i
60
+ >>>>>>> ad58e345c5de2638e34e44d69bb19b0ebebcd41e
61
+ result = ActionController::Base.helpers.number_with_precision(self, :precision => 0, :separator => ",", :delimiter => ".")
62
+ if !label.blank?
63
+ return [result, label].join("&nbsp;").html_safe
64
+ else
65
+ return result
66
+ end
67
+ end
68
+
69
+ # Inflate number, y = duration of years, f = percentage
70
+ # tested
71
+ def infla(y=40,f=2)
72
+ self.to_f*(f.to_q**y)
73
+ end
74
+
75
+ # Deflate number, y = duration of years, f = percentage
76
+ # tested
77
+ def defla(y=40,f=2)
78
+ self.to_f*((1-(f.fdiv(100)))**y)
79
+ end
80
+
81
+ # Prüfen, welche Zahl aus dem Array am nächsten an der aktuellen Dran ist
82
+ # tested
83
+ def get_closest(nrs = [], lim = :ceil)
84
+
85
+ com = {}
86
+ com_a = []
87
+ nrs.each do |n|
88
+ case lim
89
+ when :ceil
90
+ x = ((self+0.001)-n).abs
91
+ when :floor
92
+ x = ((self-0.001)-n).abs
93
+ else
94
+ raise ArgumentError, "lim must be :ceil or :floor"
95
+ end
96
+ com.merge!(x => n)
97
+ com_a << x
98
+ end
99
+ return com[com_a.min]
100
+ end
101
+
102
+ # tested
103
+ def min(ref)
104
+ <<<<<<< HEAD
105
+ [self.to_f, ref.to_f].min
106
+ =======
107
+ [self, ref].min
108
+ >>>>>>> ad58e345c5de2638e34e44d69bb19b0ebebcd41e
109
+ end
110
+
111
+ # tested
112
+ def max(ref)
113
+ <<<<<<< HEAD
114
+ [self.to_f, ref.to_f].max
115
+ =======
116
+ [self, ref].max
117
+ >>>>>>> ad58e345c5de2638e34e44d69bb19b0ebebcd41e
118
+ end
119
+
120
+ # Wert zwischen den Grenzen, ansonsten ober-oder unterkante
121
+ # tested
122
+ def min_max(m1, m2)
123
+ self.min(m2).max(m1)
124
+ end
125
+
126
+ # => tested
127
+ def fdiv(d)
128
+ self.to_f/d
129
+ end
130
+
131
+
132
+ # Finanzmathematik, Zinsen und so
133
+ def to_q
134
+ 1+(self/100.0)
135
+ end
136
+
137
+ def alpha_sum(u,o)
138
+ (self**u - self**(o+1)).fdiv(1-self)
139
+ end
140
+
141
+
142
+ def to_time(options = {})
143
+ values = [ self.to_i/3600, self.to_i / 60 % 60, self.to_i%60 ].map{ |t| t.to_s.rjust(2, '0') }
144
+ if options[:split] == true
145
+ return {:h => values[0].round, :m => values[1].round, :s => values[2].round}
146
+ elsif options[:discard_hour] == true && values[0] == "00"
147
+ return values[1,2].join(':')
148
+ else
149
+ return values.join(':')
150
+ end
151
+ end
152
+
153
+
154
+ end
155
+
156
+ Integer.class_eval do
157
+
158
+
159
+
160
+ def odd?
161
+ self%2 == 0
162
+ end
163
+
164
+ def even?
165
+ !self.odd?
166
+ end
167
+
168
+
169
+ # Cals
170
+ def to_years(options = {:s_years => "Jahre", :s_months => "Monate", :s_sep => "und"})
171
+ x = [self/12, self%12]
172
+ "#{x[0]} #{options[:s_years]} #{options[:s_sep]} #{x[1]} #{options[:s_months]}"
173
+ end
174
+
175
+ def days_to_months(options = {:s_days => "Tage", :s_months => "Monate", :s_sep => "und"})
176
+ x = [self/30, self%30]
177
+ "#{x[0]} #{options[:s_months]} #{options[:s_sep]} #{x[1]} #{options[:s_days]}"
178
+ <<<<<<< HEAD
179
+ end
180
+
181
+
182
+ # Split number in smallest prime factors
183
+ def prime_factors(options = {})
184
+ options[:nrs] ||= Math.sqrt(self).floor.prime_numbers
185
+ options[:nrs].each_with_index do |n,i|
186
+ if self%n == 0
187
+ return [n, (self/n).prime_factors(:nrs => options[:nrs])].flatten.except(1)
188
+ elsif i == options[:nrs].size-1
189
+ return [self]
190
+ end
191
+ end
192
+ end
193
+
194
+ # Create list with prime numbers up to 'self'
195
+ def prime_numbers
196
+ s = (0..self).to_a
197
+ s[0] = s[1] = nil
198
+ s.each do |p|
199
+ next unless p
200
+ break if p * p > self
201
+ (p*p).step(self, p) { |m| s[m] = nil }
202
+ end
203
+ s.compact
204
+ end
205
+
206
+ =======
207
+ end
208
+
209
+ >>>>>>> ad58e345c5de2638e34e44d69bb19b0ebebcd41e
210
+ end
211
+
212
+
213
+ Fixnum.class_eval do
214
+ def nan?
215
+ self.to_f.nan?
216
+ end
217
+ end
218
+
219
+ end
220
+
@@ -11,7 +11,7 @@ module SmartCurrency
11
11
  include InstanceMethods
12
12
  auto_attributes = []
13
13
  self.skip_time_zone_conversion_for_attributes = []
14
- attributes = self.columns.select {|c| (c.type == :integer || c.type == :decimal) && c.name != "id" }
14
+ attributes = self.columns.select {|c| (c.type == :integer || c.type == :decimal) && !c.name.match("id") }
15
15
 
16
16
  attributes.each do |a|
17
17
  define_method("#{a.name}=") do |val|
@@ -33,7 +33,9 @@ module SmartCurrency
33
33
  def currency_to_db(string)
34
34
  if string.is_a?(String)
35
35
  return (string.gsub(/\./, '').gsub(/,/, '.')).to_f
36
- else
36
+ elsif string.nil?
37
+ return 0
38
+ else
37
39
  return string
38
40
  end
39
41
  end
@@ -0,0 +1,74 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module SmartCurrency
3
+
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ def smart_currency
10
+ unless smart_currency?
11
+ include InstanceMethods
12
+ auto_attributes = []
13
+ self.skip_time_zone_conversion_for_attributes = []
14
+ <<<<<<< HEAD
15
+ attributes = self.columns.select {|c| (c.type == :integer || c.type == :decimal) && !c.name.match("id") }
16
+ =======
17
+ attributes = self.columns.select {|c| (c.type == :integer || c.type == :decimal) && c.name != "id" }
18
+ >>>>>>> ad58e345c5de2638e34e44d69bb19b0ebebcd41e
19
+
20
+ attributes.each do |a|
21
+ define_method("#{a.name}=") do |val|
22
+ self[a.name.to_sym] = currency_to_db(val)
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+
29
+ def smart_currency?
30
+ self.included_modules.include?(InstanceMethods)
31
+ end
32
+
33
+ end
34
+
35
+ module InstanceMethods # any method placed here will apply to instaces, like @hickwall
36
+
37
+ def currency_to_db(string)
38
+ if string.is_a?(String)
39
+ return (string.gsub(/\./, '').gsub(/,/, '.')).to_f
40
+ <<<<<<< HEAD
41
+ elsif string.nil?
42
+ return 0
43
+ else
44
+ =======
45
+ else
46
+ >>>>>>> ad58e345c5de2638e34e44d69bb19b0ebebcd41e
47
+ return string
48
+ end
49
+ end
50
+
51
+ def currency_to_view(decimal)
52
+ if !decimal.nil?
53
+ str = decimal.to_s.split(".")
54
+ str[1] = "0" unless str[1]
55
+ if str[1].size == 1
56
+ str[1] += "0"
57
+ end
58
+ if str[0].size == 5 || str[0].size == 6
59
+ str[0].gsub!(/\B([0-9]{3})\b/,'.\1')
60
+ elsif str[0].size > 7
61
+ str[0].gsub!(/([0-9]{3})\b/,'.\1').gsub!(/([0-9]{3}\.)/, '.\1')
62
+ else
63
+ str[0].gsub!(/\B([0-9]{3})/,'.\1')
64
+ end
65
+ str[1].size > 2 ? str[1] = str[1][0..1] : nil
66
+ return (str[0] + "," + str[1]).to_s
67
+ else
68
+ return "keine Angabe"
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+ end
@@ -53,10 +53,19 @@ module StringAndMore
53
53
 
54
54
  # Create string with german date format to Date
55
55
  def to_date
56
- matched_date = self.match(/((0|1|2|3)[0-9]{1})\.(0[0-9]{1}|11|12)\.[0-9]{4}/)
57
- raise ArgumentError, "String has no date like DD.MM.YYYY" if matched_date.nil?
56
+ # Try German
57
+ matched_date = self.match(/((0|1|2|3)[0-9]{1})\.(0[0-9]{1}|10|11|12)\.[0-9]{4}/)
58
58
 
59
- Date.new(matched_date.to_s.split(".")[2].to_i, matched_date.to_s.split(".")[1].to_i, matched_date.to_s.split(".")[0].to_i)
59
+ if !matched_date.nil?
60
+ return Date.new(matched_date.to_s.split(".")[2].to_i, matched_date.to_s.split(".")[1].to_i, matched_date.to_s.split(".")[0].to_i)
61
+ elsif matched_date.nil?
62
+ matched_date = self.match(/[0-9]{4}-(0[0-9]{1}|10|11|12)-((0|1|2|3)[0-9]{1})/)
63
+ if !matched_date.nil?
64
+ return Date.new(matched_date.to_s.split("-")[0].to_i, matched_date.to_s.split("-")[1].to_i, matched_date.to_s.split("-")[2].to_i)
65
+ end
66
+ end
67
+
68
+ raise ArgumentError, "String has no date like DD.MM.YYYY or YYYY-DD-MM" if matched_date.nil?
60
69
  end
61
70
 
62
71
 
@@ -72,11 +81,10 @@ module StringAndMore
72
81
  end
73
82
 
74
83
  def to_label(options = {:show_tooltip => false})
75
- attribute = self
76
- l = ConceptLabel::LABELS[attribute]
84
+ l = ConceptLabel::LABELS[self]
77
85
  if l.nil?
78
- ConceptLabel.create(:label => attribute, :attribute_name => attribute)# rescue nil
79
- return attribute
86
+ ConceptLabel.create(:label => self, :attribute_name => self)
87
+ return self
80
88
  else
81
89
  unless options[:show_tooltip] == true
82
90
  return l[:label]
@@ -85,19 +93,11 @@ module StringAndMore
85
93
  end
86
94
  end
87
95
  end
88
-
89
-
90
-
91
- def to_glossar(with = "", options = {:show_tooltip => false})
92
- with ||= ""
93
- attribute = self
94
- l = Glossar.find_by_attribute_name(attribute)
95
- if l.nil?
96
- Glossar.create(:label => attribute, :attribute_name => attribute)
97
- end
98
96
 
99
- return "<a href='#glossar_#{attribute.parameterize}' class='glossarlink_small'>#{attribute}#{with}</a>".html_safe
100
- end
97
+ def shuffle
98
+ self.split("").sort_by {rand}.join.humanize
99
+ end
100
+
101
101
 
102
102
  def to_foldername(sep = "_")
103
103
  # deutsch umlaute ersetzen
@@ -193,7 +193,7 @@ module StringAndMore
193
193
  self.gsub(" ", "&nbsp;").html_safe
194
194
  end
195
195
 
196
- def replace_entities(mode = :html)
196
+ def replace_entities(mode = :html, options = {})
197
197
  str = self
198
198
  Chars2Remove::ENTITIES.each do |orig, rep|
199
199
  str = str.gsub(orig, rep[mode])
@@ -0,0 +1,303 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module StringAndMore
3
+ String.class_eval do
4
+
5
+ require "chars_2_remove"
6
+ require 'digest/sha1'
7
+
8
+ # List with internation chars and their ASCII replacement
9
+ CHARS_TO_REMOVE = Chars2Remove::CHARS
10
+
11
+ # Characters for creating randdom char combinations
12
+ String::RANDOM_CHARS = {:upcase => "ABCDEFGHIJKLMNOPQRSTUVWXYZ", :downcase => "abcdefghijklmnopqrstuvwxyz", :numbers => "1234567890"}
13
+
14
+ # String charsets used for numeric encryption
15
+ STRING_CHARSETS = {
16
+ "a" => String::RANDOM_CHARS[:upcase],
17
+ "A" => String::RANDOM_CHARS[:downcase],
18
+ "1" => String::RANDOM_CHARS[:numbers],
19
+ "ä" => "äöüÄÖÜß",
20
+ "!" => '!\"§$%&/()=?+*#@,.-;:_\' ¡“”¶¢[]|{}≠¿^°≤≥∞…–‘’<>'
21
+ }
22
+
23
+ # Array with all strings which can be encrypted
24
+ STRING_BASE = STRING_CHARSETS.values.join("")
25
+
26
+ # Returns random String, for Passwords, Captachs etc..
27
+ # could create :upcase, :downcase, :numbers or :all
28
+ def self.random_string(l=12, mode = :all)
29
+ case mode
30
+ when :all
31
+ base = String::RANDOM_CHARS.values.join("").split("")
32
+ else
33
+ base = String::RANDOM_CHARS[mode].split("")
34
+ end
35
+
36
+ str = ""
37
+
38
+ l.times do
39
+ str << base.shuffle[rand(base.size-1)]
40
+ end
41
+ return str
42
+ end
43
+
44
+
45
+ # Extract boolean status from string
46
+ def to_boolean
47
+ if ['true', 'True', 'TRUE', '1'].include?(self)
48
+ return true
49
+ else
50
+ return false
51
+ end
52
+ end
53
+
54
+ # Create string with german date format to Date
55
+ def to_date
56
+ <<<<<<< HEAD
57
+ # Try German
58
+ matched_date = self.match(/((0|1|2|3)[0-9]{1})\.(0[0-9]{1}|10|11|12)\.[0-9]{4}/)
59
+
60
+ if !matched_date.nil?
61
+ return Date.new(matched_date.to_s.split(".")[2].to_i, matched_date.to_s.split(".")[1].to_i, matched_date.to_s.split(".")[0].to_i)
62
+ elsif matched_date.nil?
63
+ matched_date = self.match(/[0-9]{4}-(0[0-9]{1}|10|11|12)-((0|1|2|3)[0-9]{1})/)
64
+ if !matched_date.nil?
65
+ return Date.new(matched_date.to_s.split("-")[0].to_i, matched_date.to_s.split("-")[1].to_i, matched_date.to_s.split("-")[2].to_i)
66
+ end
67
+ end
68
+
69
+ raise ArgumentError, "String has no date like DD.MM.YYYY or YYYY-DD-MM" if matched_date.nil?
70
+ =======
71
+ matched_date = self.match(/((0|1|2|3)[0-9]{1})\.(0[0-9]{1}|11|12)\.[0-9]{4}/)
72
+ raise ArgumentError, "String has no date like DD.MM.YYYY" if matched_date.nil?
73
+
74
+ Date.new(matched_date.to_s.split(".")[2].to_i, matched_date.to_s.split(".")[1].to_i, matched_date.to_s.split(".")[0].to_i)
75
+ >>>>>>> ad58e345c5de2638e34e44d69bb19b0ebebcd41e
76
+ end
77
+
78
+
79
+ def to_number(type = :float)
80
+ extract = self.match(/[0-9\.,]{1,}/).to_s
81
+ final = extract.gsub(".", "").gsub(",", ".")
82
+ case type
83
+ when :float
84
+ return final.to_f
85
+ else
86
+ return final.to_i
87
+ end
88
+ end
89
+
90
+ def to_label(options = {:show_tooltip => false})
91
+ l = ConceptLabel::LABELS[self]
92
+ if l.nil?
93
+ ConceptLabel.create(:label => self, :attribute_name => self)
94
+ return self
95
+ else
96
+ unless options[:show_tooltip] == true
97
+ return l[:label]
98
+ else
99
+ return l[:tooltip]
100
+ end
101
+ end
102
+ end
103
+ <<<<<<< HEAD
104
+
105
+ def shuffle
106
+ self.split("").sort_by {rand}.join.humanize
107
+ end
108
+ =======
109
+
110
+ >>>>>>> ad58e345c5de2638e34e44d69bb19b0ebebcd41e
111
+
112
+
113
+ def to_glossar(with = "", options = {:show_tooltip => false})
114
+ with ||= ""
115
+ attribute = self
116
+ l = Glossar.find_by_attribute_name(attribute)
117
+ if l.nil?
118
+ Glossar.create(:label => attribute, :attribute_name => attribute)
119
+ end
120
+
121
+ return "<a href='#glossar_#{attribute.parameterize}' class='glossarlink_small'>#{attribute}#{with}</a>".html_safe
122
+ end
123
+
124
+ def to_foldername(sep = "_")
125
+ # deutsch umlaute ersetzen
126
+ parameterized_string = self.strip.gsub(/\ {2,}/ , " ").de_2_int
127
+
128
+ # Turn unwanted chars into the separator
129
+ parameterized_string.gsub!(/[^a-zA-Z0-9ÄÖÜöäüß\-_]+/, sep)
130
+ unless sep.nil? || sep.empty?
131
+ re_sep = Regexp.escape(sep)
132
+ # No more than one of the separator in a row.
133
+ parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
134
+ # Remove leading/trailing separator.
135
+ parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/, '')
136
+ end
137
+ return parameterized_string
138
+ end
139
+
140
+
141
+
142
+ def de_2_int
143
+ str = self
144
+ CHARS_TO_REMOVE.each do |de, int|
145
+ str = str.gsub(de, int)
146
+ end
147
+ str = str.gsub(" ", " ")
148
+ return str
149
+ end
150
+
151
+ def limit(l=20)
152
+ if self.size > l
153
+ s = self.size
154
+ s2 = (((self.size-1)/2).round)
155
+ first = self.slice(0..s2)
156
+ last = self.slice(s2+1..-1)
157
+
158
+ l1 = (l/2).round
159
+
160
+ "#{first.first(l1)}...#{last.last(l1)}"
161
+ else
162
+ return self
163
+ end
164
+ end
165
+
166
+
167
+
168
+
169
+ def to_datetime
170
+ date = self.split(" ").first
171
+ time = self.split(" ").last.split(":")
172
+ DateTime.new(date.split(".")[2].to_i, date.split(".")[1].to_i, date.split(".")[0].to_i, time.first.to_i, time.last.to_i)
173
+ end
174
+
175
+
176
+ def clear_html(options = {})
177
+ ActionView::Base.full_sanitizer.sanitize(self, :tags => options[:tags] )
178
+ end
179
+
180
+ def replace_html(from, to)
181
+ new_text = self
182
+ new_text = new_text.gsub("<#{from}>", "<#{to}>")
183
+ new_text = new_text.gsub("</#{from}>", "</#{to}>")
184
+ return new_text
185
+ end
186
+
187
+ def to_model
188
+ self.singularize.camelize.constantize
189
+ end
190
+
191
+ def to_a
192
+ return [self]
193
+ end
194
+
195
+ #== HTML Styling
196
+ # as the function names say
197
+
198
+ def bold
199
+ "<b>#{self}</b>".html_safe
200
+ end
201
+
202
+ def ital
203
+ "<i>#{self}</i>".html_safe
204
+ end
205
+
206
+ def span
207
+ "<span>#{self}</span>".html_safe
208
+ end
209
+
210
+ def uline
211
+ "<u>#{self}</u>".html_safe
212
+ end
213
+
214
+ def nbsp
215
+ self.gsub(" ", "&nbsp;").html_safe
216
+ end
217
+
218
+ <<<<<<< HEAD
219
+ def replace_entities(mode = :html, options = {})
220
+ =======
221
+ def replace_entities(mode = :html)
222
+ >>>>>>> ad58e345c5de2638e34e44d69bb19b0ebebcd41e
223
+ str = self
224
+ Chars2Remove::ENTITIES.each do |orig, rep|
225
+ str = str.gsub(orig, rep[mode])
226
+ end
227
+ return str.html_safe
228
+ end
229
+
230
+ def add_brs
231
+ return self.gsub("\n", "<br />")
232
+ end
233
+
234
+ #== colorization in console
235
+
236
+ def colorize(color_code)
237
+ "\e[#{color_code};40m#{self}\e[0m"
238
+ end
239
+
240
+ def red
241
+ colorize(31)
242
+ end
243
+
244
+ def green
245
+ colorize(32)
246
+ end
247
+
248
+ def yellow
249
+ colorize(33)
250
+ end
251
+
252
+ def pink
253
+ colorize(35)
254
+ end
255
+
256
+
257
+ #== Numerische encription
258
+ # cool thing for simple encrypt and decrypt strings
259
+
260
+ def numberize(options = {})
261
+ # Basisarray das alle zeichen enthält die verschlüsselt werden können
262
+ string_array = STRING_BASE.split("")
263
+
264
+ # Nur Zahlen und buchstaben für die verschlüsselung/mix nehmen wg. URLs
265
+ string_array_filtered = string_array.select {|s| !s.match(/[a-zA-Z0-9\-_]/).nil? }
266
+ splitted = self.split("")
267
+
268
+ numbered_string = ""
269
+
270
+ splitted.each do |s|
271
+ position = string_array.index(s)
272
+ if !position.nil?
273
+ numbered_string << (position.to_s.rjust(2, "0")+string_array_filtered[rand(string_array_filtered.size-1)])
274
+ end
275
+ end
276
+
277
+ return options[:base_64] == true ? Base64.encode64(numbered_string) : numbered_string
278
+ end
279
+
280
+ def denumberize(options = {})
281
+ string_array = STRING_BASE.split("")
282
+ real_string = ""
283
+ (options[:base_64] == true ? Base64.decode64(self) : self ).scan(/[0-9]{2}.{1}/).each do |s|
284
+ real_string << string_array[s.first(2).to_i]
285
+ end
286
+ return real_string
287
+ end
288
+
289
+
290
+
291
+ end
292
+
293
+ Symbol.class_eval do
294
+
295
+ def to_label(options = {})
296
+ self.to_s.to_label(options)
297
+ end
298
+
299
+ def gsub(old, repl)
300
+ self.to_s.gsub(old, repl)
301
+ end
302
+ end
303
+ end