lite-ruby 1.3.1 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -1
  3. data/Gemfile.lock +1 -1
  4. data/README.md +26 -6
  5. data/docs/HASH.md +13 -0
  6. data/lib/generators/lite/ruby/install_generator.rb +0 -2
  7. data/lib/generators/lite/ruby/templates/install.rb +18 -6
  8. data/lib/lite/ruby.rb +2 -15
  9. data/lib/lite/ruby/all.rb +16 -0
  10. data/lib/lite/ruby/array.rb +218 -220
  11. data/lib/lite/ruby/boolean.rb +17 -19
  12. data/lib/lite/ruby/date.rb +13 -20
  13. data/lib/lite/ruby/enumerable.rb +153 -155
  14. data/lib/lite/ruby/formats/date_stamps.yml +34 -0
  15. data/lib/lite/ruby/formats/date_units.yml +42 -0
  16. data/lib/lite/ruby/formats/integer_roman_numerals.yml +13 -0
  17. data/lib/lite/ruby/formats/string_transliterations.yml +189 -0
  18. data/lib/lite/ruby/formats/time_stamps.yml +42 -0
  19. data/lib/lite/ruby/formats/time_units.yml +28 -0
  20. data/lib/lite/ruby/hash.rb +313 -301
  21. data/lib/lite/ruby/helpers/date_time_helper.rb +24 -0
  22. data/lib/lite/ruby/integer.rb +62 -63
  23. data/lib/lite/ruby/kernel.rb +19 -21
  24. data/lib/lite/ruby/numeric.rb +175 -177
  25. data/lib/lite/ruby/object.rb +128 -130
  26. data/lib/lite/ruby/open_struct.rb +17 -19
  27. data/lib/lite/ruby/range.rb +19 -21
  28. data/lib/lite/ruby/safe/object.rb +10 -8
  29. data/lib/lite/ruby/safe/string.rb +8 -7
  30. data/lib/lite/ruby/string.rb +348 -384
  31. data/lib/lite/ruby/struct.rb +7 -9
  32. data/lib/lite/ruby/time.rb +25 -30
  33. data/lib/lite/ruby/version.rb +1 -1
  34. metadata +10 -5
  35. data/lib/lite/ruby/configuration.rb +0 -38
  36. data/lib/lite/ruby/helpers/date_helper.rb +0 -107
  37. data/lib/lite/ruby/helpers/time_helper.rb +0 -86
@@ -1,485 +1,449 @@
1
1
  # frozen_string_literal: false
2
2
 
3
- if Lite::Ruby.configuration.monkey_patches.include?('string')
4
- class String
5
-
6
- TRANSLITERATIONS = {
7
- 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A', 'Æ' => 'Ae',
8
- 'Ç' => 'C', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ì' => 'I', 'Í' => 'I',
9
- 'Î' => 'I', 'Ï' => 'I', 'Ð' => 'D', 'Ñ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O',
10
- 'Õ' => 'O', 'Ö' => 'O', 'Ø' => 'O', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U',
11
- 'Ý' => 'Y', 'Þ' => 'Th', 'ß' => 'ss', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a',
12
- 'ä' => 'a', 'å' => 'a', 'æ' => 'ae', 'ç' => 'c', 'è' => 'e', 'é' => 'e', 'ê' => 'e',
13
- 'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ð' => 'd', 'ñ' => 'n',
14
- 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ø' => 'o', 'ù' => 'u',
15
- 'ú' => 'u', 'û' => 'u', 'ü' => 'u', 'ý' => 'y', 'þ' => 'th', 'ÿ' => 'y', 'Ā' => 'A',
16
- 'ā' => 'a', 'Ă' => 'A', 'ă' => 'a', 'Ą' => 'A', 'ą' => 'a', 'Ć' => 'C', 'ć' => 'c',
17
- 'Ĉ' => 'C', 'ĉ' => 'c', 'Ċ' => 'C', 'ċ' => 'c', 'Č' => 'C', 'č' => 'c', 'Ď' => 'D',
18
- 'ď' => 'd', 'Đ' => 'D', 'đ' => 'd', 'Ē' => 'E', 'ē' => 'e', 'Ĕ' => 'E', 'ĕ' => 'e',
19
- 'Ė' => 'E', 'ė' => 'e', 'Ę' => 'E', 'ę' => 'e', 'Ě' => 'E', 'ě' => 'e', 'Ĝ' => 'G',
20
- 'ĝ' => 'g', 'Ğ' => 'G', 'ğ' => 'g', 'Ġ' => 'G', 'ġ' => 'g', 'Ģ' => 'G', 'ģ' => 'g',
21
- 'Ĥ' => 'H', 'ĥ' => 'h', 'Ħ' => 'H', 'ħ' => 'h', 'Ĩ' => 'I', 'ĩ' => 'i', 'Ī' => 'I',
22
- 'ī' => 'i', 'Ĭ' => 'I', 'ĭ' => 'i', 'Į' => 'I', 'į' => 'i', 'İ' => 'I', 'ı' => 'i',
23
- 'IJ' => 'Ij', 'ij' => 'ij', 'Ĵ' => 'J', 'ĵ' => 'j', 'Ķ' => 'K', 'ķ' => 'k', 'ĸ' => 'k',
24
- 'Ĺ' => 'L', 'ĺ' => 'l', 'Ļ' => 'L', 'ļ' => 'l', 'Ľ' => 'L', 'ľ' => 'l', 'Ŀ' => 'L',
25
- 'ŀ' => 'l', 'Ł' => 'L', 'ł' => 'l', 'Ń' => 'N', 'ń' => 'n', 'Ņ' => 'N', 'ņ' => 'n',
26
- 'Ň' => 'N', 'ň' => 'n', 'ʼn' => 'n', 'Ŋ' => 'Ng', 'ŋ' => 'ng', 'Ō' => 'O', 'ō' => 'o',
27
- 'Ŏ' => 'O', 'ŏ' => 'o', 'Ő' => 'O', 'ő' => 'o', 'Œ' => 'OE', 'œ' => 'oe', 'Ŕ' => 'R',
28
- 'ŕ' => 'r', 'Ŗ' => 'R', 'ŗ' => 'r', 'Ř' => 'R', 'ř' => 'r', 'Ś' => 'S', 'ś' => 's',
29
- 'Ŝ' => 'S', 'ŝ' => 's', 'Ş' => 'S', 'ş' => 's', 'Š' => 'S', 'š' => 's', 'Ţ' => 'T',
30
- 'ţ' => 't', 'Ť' => 'T', 'ť' => 't', 'Ŧ' => 'T', 'ŧ' => 't', 'Ũ' => 'U', 'ũ' => 'u',
31
- 'Ū' => 'U', 'ū' => 'u', 'Ŭ' => 'U', 'ŭ' => 'u', 'Ů' => 'U', 'ů' => 'u', 'Ű' => 'U',
32
- 'ű' => 'u', 'Ų' => 'U', 'ų' => 'u', 'Ŵ' => 'W', 'ŵ' => 'w', 'Ŷ' => 'Y', 'ŷ' => 'y',
33
- 'Ÿ' => 'Y', 'Ź' => 'Z', 'ź' => 'z', 'Ż' => 'Z', 'ż' => 'z', 'Ž' => 'Z', 'ž' => 'z'
34
- }.freeze
35
-
36
- def acronym
37
- gsub(/(([a-zA-Z0-9])([a-zA-Z0-9])*)./, '\\2') || self
38
- end
39
-
40
- def acronym!
41
- replace(acronym)
42
- end
3
+ require 'yaml' unless defined?(YAML)
43
4
 
44
- def any?(*keys)
45
- keys.any? { |key| include?(key) }
46
- end
5
+ class String
47
6
 
48
- def camelize!(first_letter = :upper)
49
- replace(camelize(first_letter))
50
- end
7
+ TRANSLITERATIONS = YAML.load_file(
8
+ File.expand_path('formats/string_transliterations.yml', File.dirname(__FILE__))
9
+ ).freeze
51
10
 
52
- def capitalized?
53
- capitalize == self
54
- end
11
+ def acronym
12
+ gsub(/(([a-zA-Z0-9])([a-zA-Z0-9])*)./, '\\2') || self
13
+ end
55
14
 
56
- def classify!
57
- replace(classify)
58
- end
15
+ def acronym!
16
+ replace(acronym)
17
+ end
59
18
 
60
- def dasherize!
61
- replace(dasherize)
62
- end
19
+ def any?(*keys)
20
+ keys.any? { |key| include?(key) }
21
+ end
63
22
 
64
- def deconstantize!
65
- replace(deconstantize)
66
- end
23
+ def camelize!(first_letter = :upper)
24
+ replace(camelize(first_letter))
25
+ end
67
26
 
68
- def dedupe(pattern)
69
- dup.dedupe!(pattern)
70
- end
27
+ def capitalized?
28
+ capitalize == self
29
+ end
71
30
 
72
- def dedupe!(pattern)
73
- pattern.each_char { |char| gsub!(/#{Regexp.escape(char)}{2,}/, char) }
74
- self
75
- end
31
+ def classify!
32
+ replace(classify)
33
+ end
76
34
 
77
- def demodulize!
78
- replace(demodulize)
79
- end
35
+ def dasherize!
36
+ replace(dasherize)
37
+ end
80
38
 
81
- def domain
82
- return self unless self =~ %r{^(?:\w+://)?([^/?]+)(?:/|\?|$)}
39
+ def deconstantize!
40
+ replace(deconstantize)
41
+ end
83
42
 
84
- Regexp.last_match(1)
85
- end
43
+ def dedupe(pattern)
44
+ dup.dedupe!(pattern)
45
+ end
86
46
 
87
- def downcase?
88
- downcase == self
89
- end
47
+ def dedupe!(pattern)
48
+ pattern.each_char { |char| gsub!(/#{Regexp.escape(char)}{2,}/, char) }
49
+ self
50
+ end
90
51
 
91
- def each_word(&block)
92
- words.each(&block)
93
- end
52
+ def demodulize!
53
+ replace(demodulize)
54
+ end
94
55
 
95
- def ellipsize(ellipsize_at, options = {})
96
- return self if length <= ellipsize_at
56
+ def domain
57
+ return self unless self =~ %r{^(?:\w+://)?([^/?]+)(?:/|\?|$)}
97
58
 
98
- separator = options[:separator] || '...'
99
- offset = options[:offset] || 4
59
+ Regexp.last_match(1)
60
+ end
100
61
 
101
- "#{self[0, offset]}#{separator}#{self[-offset, offset]}"
102
- end
62
+ def downcase?
63
+ downcase == self
64
+ end
103
65
 
104
- def format(*args)
105
- super(self, *args.flatten)
106
- end
66
+ def each_word(&block)
67
+ words.each(&block)
68
+ end
107
69
 
108
- def headerize
109
- squish.each_word(&:capitalize!).join(' ')
110
- end
70
+ def ellipsize(ellipsize_at, options = {})
71
+ return self if length <= ellipsize_at
111
72
 
112
- def headerize!
113
- replace(headerize)
114
- end
73
+ separator = options[:separator] || '...'
74
+ offset = options[:offset] || 4
115
75
 
116
- def humanize!(capitalize: true)
117
- replace(humanize(capitalize: capitalize))
118
- end
76
+ "#{self[0, offset]}#{separator}#{self[-offset, offset]}"
77
+ end
119
78
 
120
- def index_all(pattern)
121
- pattern = pattern.to_s if pattern.is_a?(Numeric)
122
- arr_indexes = []
123
- srch_index = rindex(pattern)
79
+ def format(*args)
80
+ super(self, *args.flatten)
81
+ end
124
82
 
125
- while srch_index
126
- temp_string = self[0..(srch_index - 1)]
127
- arr_indexes << srch_index
128
- srch_index = srch_index.zero? ? nil : temp_string.rindex(pattern)
129
- end
83
+ def headerize
84
+ squish.each_word(&:capitalize!).join(' ')
85
+ end
130
86
 
131
- arr_indexes.reverse
132
- end
87
+ def headerize!
88
+ replace(headerize)
89
+ end
133
90
 
134
- def labelize(capitalize: true)
135
- dup.labelize!(capitalize: capitalize)
136
- end
91
+ def humanize!(capitalize: true)
92
+ replace(humanize(capitalize: capitalize))
93
+ end
137
94
 
138
- def labelize!(capitalize: true)
139
- underscore!
140
- tr!('_', ' ')
141
- squish!
142
- gsub!(/([a-z\d]*)/i, &:downcase)
143
- gsub!(/\A\w/) { |str| capitalize ? str.upcase : str }
144
- gsub!(/ id\z/, ' ID') || self
145
- end
95
+ def index_all(pattern)
96
+ pattern = pattern.to_s if pattern.is_a?(Numeric)
97
+ arr_indexes = []
98
+ srch_index = rindex(pattern)
146
99
 
147
- def lchomp(match)
148
- dup.lchomp!(match)
100
+ while srch_index
101
+ temp_string = self[0..(srch_index - 1)]
102
+ arr_indexes << srch_index
103
+ srch_index = srch_index.zero? ? nil : temp_string.rindex(pattern)
149
104
  end
150
105
 
151
- def lchomp!(match)
152
- return self unless index(match)
106
+ arr_indexes.reverse
107
+ end
153
108
 
154
- self[0...match.size] = ''
155
- self
156
- end
109
+ def labelize(capitalize: true)
110
+ dup.labelize!(capitalize: capitalize)
111
+ end
157
112
 
158
- def methodize
159
- dup.methodize!
160
- end
113
+ def labelize!(capitalize: true)
114
+ underscore!
115
+ tr!('_', ' ')
116
+ squish!
117
+ gsub!(/([a-z\d]*)/i, &:downcase)
118
+ gsub!(/\A\w/) { |str| capitalize ? str.upcase : str }
119
+ gsub!(/ id\z/, ' ID') || self
120
+ end
161
121
 
162
- def methodize!
163
- gsub!(/([A-Z]+)([A-Z])/, '\1_\2')
164
- gsub!(/([a-z])([A-Z])/, '\1_\2')
165
- gsub!('/', '__')
166
- gsub!('::', '__')
167
- downcase! || self
168
- end
122
+ def lchomp(match)
123
+ dup.lchomp!(match)
124
+ end
169
125
 
170
- def modulize
171
- dup.modulize!
172
- end
126
+ def lchomp!(match)
127
+ return self unless index(match)
173
128
 
174
- def modulize!
175
- gsub!(/__(.?)/) { "::#{$1.upcase}" }
176
- gsub!(%r{/(.?)}) { "::#{$1.upcase}" }
177
- gsub!(/(?:_+|-+)([a-z])/) { $1.upcase }
178
- gsub!(/(\A|\s)([a-z])/) { $1 + $2.upcase } || self
179
- end
129
+ self[0...match.size] = ''
130
+ self
131
+ end
180
132
 
181
- def mixedcase?
182
- !upcase? && !downcase?
183
- end
133
+ def methodize
134
+ dup.methodize!
135
+ end
184
136
 
185
- def non_possessive
186
- dup.non_possessive!
187
- end
137
+ def methodize!
138
+ gsub!(/([A-Z]+)([A-Z])/, '\1_\2')
139
+ gsub!(/([a-z])([A-Z])/, '\1_\2')
140
+ gsub!('/', '__')
141
+ gsub!('::', '__')
142
+ downcase! || self
143
+ end
188
144
 
189
- def non_possessive!
190
- return self unless possessive?
145
+ def modulize
146
+ dup.modulize!
147
+ end
191
148
 
192
- chomp!("'s") || chomp!("'") || self
193
- end
149
+ def modulize!
150
+ gsub!(/__(.?)/) { "::#{$1.upcase}" }
151
+ gsub!(%r{/(.?)}) { "::#{$1.upcase}" }
152
+ gsub!(/(?:_+|-+)([a-z])/) { $1.upcase }
153
+ gsub!(/(\A|\s)([a-z])/) { $1 + $2.upcase } || self
154
+ end
194
155
 
195
- def ordinal
196
- to_i.ordinal
197
- end
156
+ def mixedcase?
157
+ !upcase? && !downcase?
158
+ end
198
159
 
199
- def ordinalize
200
- to_i.ordinalize
201
- end
160
+ def non_possessive
161
+ dup.non_possessive!
162
+ end
202
163
 
203
- def parameterize!(separator: '-')
204
- replace(parameterize(separator: separator))
205
- end
164
+ def non_possessive!
165
+ return self unless possessive?
206
166
 
207
- def pathize
208
- dup.pathize!
209
- end
167
+ chomp!("'s") || chomp!("'") || self
168
+ end
210
169
 
211
- def pathize!
212
- gsub!(/([A-Z]+)([A-Z])/, '\1_\2')
213
- gsub!(/([a-z])([A-Z])/, '\1_\2')
214
- gsub!('__', '/')
215
- gsub!('::', '/')
216
- gsub!(/\s+/, '')
217
- gsub!(/[?%*:|"<>.]+/, '')
218
- downcase! || self
219
- end
170
+ def ordinal
171
+ to_i.ordinal
172
+ end
220
173
 
221
- def pollute(delimiter = '^--^--^')
222
- chars.map { |chr| "#{chr}#{delimiter}" }.join
223
- end
174
+ def ordinalize
175
+ to_i.ordinalize
176
+ end
224
177
 
225
- def pollute!(delimiter = '^--^--^')
226
- replace(pollute(delimiter))
227
- end
178
+ def parameterize!(separator: '-')
179
+ replace(parameterize(separator: separator))
180
+ end
228
181
 
229
- def pop
230
- self[-1]
231
- end
182
+ def pathize
183
+ dup.pathize!
184
+ end
232
185
 
233
- def possessive
234
- return self if possessive?
186
+ def pathize!
187
+ gsub!(/([A-Z]+)([A-Z])/, '\1_\2')
188
+ gsub!(/([a-z])([A-Z])/, '\1_\2')
189
+ gsub!('__', '/')
190
+ gsub!('::', '/')
191
+ gsub!(/\s+/, '')
192
+ gsub!(/[?%*:|"<>.]+/, '')
193
+ downcase! || self
194
+ end
235
195
 
236
- possession = end_with?('s') ? "'" : "'s"
237
- "#{self}#{possession}"
238
- end
196
+ def pollute(delimiter = '^--^--^')
197
+ chars.map { |chr| "#{chr}#{delimiter}" }.join
198
+ end
239
199
 
240
- def possessive!
241
- replace(possessive)
242
- end
200
+ def pollute!(delimiter = '^--^--^')
201
+ replace(pollute(delimiter))
202
+ end
243
203
 
244
- def possessive?
245
- %w['s s'].any? { |pos| end_with?(pos) }
246
- end
204
+ def pop
205
+ self[-1]
206
+ end
247
207
 
248
- def push(string)
249
- replace(concat(string))
250
- end
208
+ def possessive
209
+ return self if possessive?
251
210
 
252
- # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
253
- def quote(type = :double, amount = nil)
254
- if type.is_a?(Integer)
255
- tmp = amount
256
- amount = type
257
- type = tmp || :mixed
258
- else
259
- amount ||= 1
260
- end
211
+ possession = end_with?('s') ? "'" : "'s"
212
+ "#{self}#{possession}"
213
+ end
261
214
 
262
- case type.to_s
263
- when "'", 'single', 's', '1'
264
- f = "'" * amount
265
- b = f
266
- when '"', 'double', 'd', '2'
267
- f = '"' * amount
268
- b = f
269
- when '`', 'back', 'backtick', 'b', '-1'
270
- f = '`' * amount
271
- b = f
272
- when "`'", 'bracket', 'sb'
273
- f = '`' * amount
274
- b = "'" * amount
275
- when "'\"", 'mixed', 'm', 'Integer'
276
- c = (amount.to_f / 2).to_i
277
- f = '"' * c
278
- b = f
279
-
280
- if amount.odd?
281
- f = "'#{f}"
282
- b += "'"
283
- end
284
- else
285
- raise ArgumentError, "Invalid quote type: #{type.inspect}"
286
- end
215
+ def possessive!
216
+ replace(possessive)
217
+ end
287
218
 
288
- "#{f}#{self}#{b}"
289
- end
290
- # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
219
+ def possessive?
220
+ %w['s s'].any? { |pos| end_with?(pos) }
221
+ end
291
222
 
292
- def quote!(type = :double, amount = nil)
293
- replace(quote(type, amount))
294
- end
223
+ def push(string)
224
+ replace(concat(string))
225
+ end
295
226
 
296
- def remove_tags
297
- dup.remove_tags!
227
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
228
+ def quote(type = :double, amount = nil)
229
+ if type.is_a?(Integer)
230
+ tmp = amount
231
+ amount = type
232
+ type = tmp || :mixed
233
+ else
234
+ amount ||= 1
235
+ end
236
+
237
+ case type.to_s
238
+ when "'", 'single', 's', '1'
239
+ f = "'" * amount
240
+ b = f
241
+ when '"', 'double', 'd', '2'
242
+ f = '"' * amount
243
+ b = f
244
+ when '`', 'back', 'backtick', 'b', '-1'
245
+ f = '`' * amount
246
+ b = f
247
+ when "`'", 'bracket', 'sb'
248
+ f = '`' * amount
249
+ b = "'" * amount
250
+ when "'\"", 'mixed', 'm', 'Integer'
251
+ c = (amount.to_f / 2).to_i
252
+ f = '"' * c
253
+ b = f
254
+
255
+ if amount.odd?
256
+ f = "'#{f}"
257
+ b += "'"
258
+ end
259
+ else
260
+ raise ArgumentError, "Invalid quote type: #{type.inspect}"
298
261
  end
299
262
 
300
- def remove_tags!
301
- gsub!(%r{</?[^>]*>}, '') || self
302
- end
263
+ "#{f}#{self}#{b}"
264
+ end
265
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
303
266
 
304
- def rotate(amount = 1)
305
- dup.rotate!(amount)
306
- end
267
+ def quote!(type = :double, amount = nil)
268
+ replace(quote(type, amount))
269
+ end
307
270
 
308
- def rotate!(amount = 1)
309
- amount += size if amount.negative?
310
- slice!(amount, size - amount) + slice!(0, amount)
311
- end
271
+ def remove_tags
272
+ dup.remove_tags!
273
+ end
312
274
 
313
- # rubocop:disable Metrics/MethodLength
314
- def safe_encode(target_encoding, replacement = '')
315
- encode(target_encoding)
316
- rescue Encoding::InvalidByteSequenceError
317
- force_encoding(target_encoding).scrub!(replacement)
318
- rescue Encoding::UndefinedConversionError
319
- encode(
320
- target_encoding,
321
- invalid: :replace,
322
- undef: :replace,
323
- replace: replacement,
324
- UNIVERSAL_NEWLINE_DECORATOR: true
325
- )
326
- end
327
- # rubocop:enable Metrics/MethodLength
275
+ def remove_tags!
276
+ gsub!(%r{</?[^>]*>}, '') || self
277
+ end
328
278
 
329
- def safe_encode!(target_encoding, replacement = '')
330
- replace(safe_encode(target_encoding, replacement))
331
- end
279
+ def rotate(amount = 1)
280
+ dup.rotate!(amount)
281
+ end
332
282
 
333
- def sample(separator = ' ')
334
- split(separator).sample
335
- end
283
+ def rotate!(amount = 1)
284
+ amount += size if amount.negative?
285
+ slice!(amount, size - amount) + slice!(0, amount)
286
+ end
336
287
 
337
- def sample!(separator = ' ')
338
- replace(sample(separator))
339
- end
288
+ # rubocop:disable Metrics/MethodLength
289
+ def safe_encode(target_encoding, replacement = '')
290
+ encode(target_encoding)
291
+ rescue Encoding::InvalidByteSequenceError
292
+ force_encoding(target_encoding).scrub!(replacement)
293
+ rescue Encoding::UndefinedConversionError
294
+ encode(
295
+ target_encoding,
296
+ invalid: :replace,
297
+ undef: :replace,
298
+ replace: replacement,
299
+ UNIVERSAL_NEWLINE_DECORATOR: true
300
+ )
301
+ end
302
+ # rubocop:enable Metrics/MethodLength
340
303
 
341
- def shift(*patterns)
342
- dup.shift!(*patterns)
343
- end
304
+ def safe_encode!(target_encoding, replacement = '')
305
+ replace(safe_encode(target_encoding, replacement))
306
+ end
344
307
 
345
- def shift!(*patterns)
346
- return self[0] if patterns.empty?
308
+ def sample(separator = ' ')
309
+ split(separator).sample
310
+ end
347
311
 
348
- patterns.each_with_object(self) { |pat, str| str.sub!(pat, '') }
349
- end
312
+ def sample!(separator = ' ')
313
+ replace(sample(separator))
314
+ end
350
315
 
351
- def shuffle(separator = '')
352
- split(separator).shuffle.join
353
- end
316
+ def shift(*patterns)
317
+ dup.shift!(*patterns)
318
+ end
354
319
 
355
- def shuffle!(separator = '')
356
- replace(shuffle(separator))
357
- end
320
+ def shift!(*patterns)
321
+ return self[0] if patterns.empty?
358
322
 
359
- def sift(keep)
360
- keep = case keep
361
- when String then keep.chars
362
- when Array then keep.map(&:to_s)
363
- when Range then keep.to_a.map(&:to_s)
364
- else raise TypeError, "Invalid parameter: #{keep.inspect}"
365
- end
323
+ patterns.each_with_object(self) { |pat, str| str.sub!(pat, '') }
324
+ end
366
325
 
367
- chars.keep_if { |chr| keep.include?(chr) }.join
368
- end
326
+ def shuffle(separator = '')
327
+ split(separator).shuffle.join
328
+ end
369
329
 
370
- def sift!(keep)
371
- replace(sift(keep))
372
- end
330
+ def shuffle!(separator = '')
331
+ replace(shuffle(separator))
332
+ end
373
333
 
374
- def slugify
375
- dup.slugify!
376
- end
334
+ def sift(keep)
335
+ keep = case keep
336
+ when String then keep.chars
337
+ when Array then keep.map(&:to_s)
338
+ when Range then keep.to_a.map(&:to_s)
339
+ else raise TypeError, "Invalid parameter: #{keep.inspect}"
340
+ end
377
341
 
378
- def slugify!
379
- gsub!(/[^\x00-\x7F]+/, '')
380
- gsub!(/[^\w_ \-]+/i, '')
381
- gsub!(/[ \-]+/i, '-')
382
- gsub!(/^-|-$/i, '')
383
- downcase! || self
384
- end
342
+ chars.keep_if { |chr| keep.include?(chr) }.join
343
+ end
385
344
 
386
- def sort
387
- chars.sort.join
388
- end
345
+ def sift!(keep)
346
+ replace(sift(keep))
347
+ end
389
348
 
390
- def sort!
391
- replace(sort)
392
- end
349
+ def slugify
350
+ dup.slugify!
351
+ end
393
352
 
394
- def transliterize
395
- TRANSLITERATIONS.each_with_object(dup) { |(k, v), s| s.gsub!(k, v) }
396
- end
353
+ def slugify!
354
+ gsub!(/[^\x00-\x7F]+/, '')
355
+ gsub!(/[^\w \-]+/i, '')
356
+ gsub!(/[ \-]+/i, '-')
357
+ gsub!(/^-|-$/i, '')
358
+ downcase! || self
359
+ end
397
360
 
398
- def transliterize!
399
- replace(transliterize)
400
- end
361
+ def sort
362
+ chars.sort.join
363
+ end
401
364
 
402
- def titleize!
403
- replace(titleize)
404
- end
365
+ def sort!
366
+ replace(sort)
367
+ end
405
368
 
406
- def truncate_words(word_count, options = {})
407
- omission = options[:omission] || '...'
408
- seperator = options[:separator] || /\s+/
369
+ def transliterize
370
+ TRANSLITERATIONS.each_with_object(dup) { |(k, v), s| s.gsub!(k, v) }
371
+ end
409
372
 
410
- seperator = Regexp.escape(seperator.to_s) unless seperator.is_a(Regexp)
411
- return self unless /\A((?:.+?#{seperator}){#{word_count - 1}}.+?)#{seperator}.*/m.match?(self)
373
+ def transliterize!
374
+ replace(transliterize)
375
+ end
412
376
 
413
- "#{::Regexp.last_match(1)}#{omission}"
414
- end
377
+ def titleize!
378
+ replace(titleize)
379
+ end
415
380
 
416
- def upcase?
417
- upcase == self
418
- end
381
+ def upcase?
382
+ upcase == self
383
+ end
419
384
 
420
- def underscore!
421
- replace(underscore)
422
- end
385
+ def underscore!
386
+ replace(underscore)
387
+ end
423
388
 
424
- def unpollute(delimiter = '^--^--^')
425
- dup.unpollute!(delimiter)
426
- end
389
+ def unpollute(delimiter = '^--^--^')
390
+ dup.unpollute!(delimiter)
391
+ end
427
392
 
428
- def unpollute!(delimiter = '^--^--^')
429
- gsub!(delimiter, '') || self
430
- end
393
+ def unpollute!(delimiter = '^--^--^')
394
+ gsub!(delimiter, '') || self
395
+ end
431
396
 
432
- def unquote
433
- dup.unquote!
434
- end
397
+ def unquote
398
+ dup.unquote!
399
+ end
435
400
 
436
- def unquote!
437
- [0, -1].each do |i|
438
- case self[i, 1]
439
- when "'", '"', '`' then self[i] = ''
440
- end
401
+ def unquote!
402
+ [0, -1].each do |i|
403
+ case self[i, 1]
404
+ when "'", '"', '`' then self[i] = ''
441
405
  end
442
-
443
- self
444
406
  end
445
407
 
446
- def unshift(*patterns)
447
- patterns.each_with_object('') { |pat, str| str << pat }
448
- .concat(self)
449
- end
450
-
451
- def unshift!(*patterns)
452
- replace(unshift(*patterns))
453
- end
408
+ self
409
+ end
454
410
 
455
- def words
456
- split(/\s+/)
457
- end
411
+ def unshift(*patterns)
412
+ patterns.each_with_object('') { |pat, str| str << pat }
413
+ .concat(self)
414
+ end
458
415
 
459
- def words_without_punctuation
460
- str = dup
461
- str.gsub!(%r{[.?¿¡…!,::;—"。?!、‘“”„«»〈〉《》,/\[\]]}, ' ')
462
- str.gsub!('- ', ' ')
463
- str.squeeze!(' ')
464
- str.strip!
465
- str.words
466
- end
416
+ def unshift!(*patterns)
417
+ replace(unshift(*patterns))
418
+ end
467
419
 
468
- def variablize
469
- "@#{gsub(/\W/, '_')}"
470
- end
420
+ def words
421
+ split(/\s+/)
422
+ end
471
423
 
472
- def variablize!
473
- replace(variablize)
474
- end
424
+ def words_without_punctuation
425
+ str = dup
426
+ str.gsub!(%r{[.?¿¡…!,::;—"。?!、‘“”„«»〈〉《》,/\[\]]}, ' ')
427
+ str.gsub!('- ', ' ')
428
+ str.squeeze!(' ')
429
+ str.strip!
430
+ str.words
431
+ end
475
432
 
476
- alias camelcase! camelize!
477
- alias labelcase labelize
478
- alias labelcase! labelize!
479
- alias snakecase! underscore!
480
- alias titlecase! titleize!
433
+ def variablize
434
+ "@#{gsub(/\W/, '_')}"
435
+ end
481
436
 
437
+ def variablize!
438
+ replace(variablize)
482
439
  end
483
440
 
484
- require 'lite/ruby/safe/string' unless defined?(ActiveSupport)
441
+ alias camelcase! camelize!
442
+ alias labelcase labelize
443
+ alias labelcase! labelize!
444
+ alias snakecase! underscore!
445
+ alias titlecase! titleize!
446
+
485
447
  end
448
+
449
+ require 'lite/ruby/safe/string' unless defined?(ActiveSupport)