Module: VV::StringMethods
- Included in:
- String
- Defined in:
- lib/vv/string_methods.rb
Defined Under Namespace
Modules: ClassMethods, SharedInstanceAndClassMethods
Class Method Summary
collapse
Instance Method Summary
collapse
Class Method Details
.included(base) ⇒ Object
4
5
6
7
8
9
10
11
12
13
14
|
# File 'lib/vv/string_methods.rb', line 4
def self.included(base)
base.instance_eval do
extend(ClassMethods)
extend(SharedInstanceAndClassMethods)
include(SharedInstanceAndClassMethods)
alias_method :starts_with?, :start_with?
alias_method :ends_with?, :end_with?
alias_method :includes?, :include?
end
end
|
Instance Method Details
#_ensure_pluralize_available! ⇒ Object
466
467
468
469
470
|
# File 'lib/vv/string_methods.rb', line 466
def _ensure_pluralize_available!
message = "String does not define pluralize."
pluralize_available = self.respond_to? :pluralize
raise NotImplementedError, message unless pluralize_available
end
|
#_ensure_singularize_available! ⇒ Object
472
473
474
475
476
|
# File 'lib/vv/string_methods.rb', line 472
def _ensure_singularize_available!
message = "String does not define singularize."
singularize_available = self.respond_to? :singularize
raise NotImplementedError, message unless singularize_available
end
|
#_numeral_postfixes ⇒ Object
379
380
381
382
383
384
|
# File 'lib/vv/string_methods.rb', line 379
def _numeral_postfixes
{ k: 1000,
m: 1000_000,
b: 1000_000_000,
t: 1000_000_000_000 }.stringify_keys
end
|
#after(string, safe: true) ⇒ Object
122
123
124
125
126
127
128
129
130
131
|
# File 'lib/vv/string_methods.rb', line 122
def after(string, safe: true)
if safe && ! self.starts_with?(string)
message = "String does not start with #{string}"
raise RuntimeError, message
elsif not self.starts_with?(string)
return self
end
self[string.size..-1]
end
|
#cli_print(width: nil, padding: nil, position: nil, hard_wrap: false) ⇒ Object
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
|
# File 'lib/vv/string_methods.rb', line 592
def cli_print width: nil,
padding: nil,
position: nil,
hard_wrap: false
width ||= 80
position ||= 0
padding ||= 0
raise NotImplemented if hard_wrap
raise NotImplemented if self.includes? newline
pad_length = padding - position
position += pad_length
print pad_length.spaces
unstyled_length = self.unstyled.length
remaining_length = width - position
if unstyled_length <= remaining_length
print self
position += unstyled_length
return position
end
space_index = self[0..remaining_length].rindex(" ")
space_index ||= self.index(" ")
if space_index
sub = self[0..space_index]
print sub
puts
position = 0
start = space_index + 1
return self[start..-1].cli_print width: width,
padding: padding,
position: position,
hard_wrap: hard_wrap
else
print self
puts
position = 0
end
return position
end
|
#cli_puts(**kwargs) ⇒ Object
588
589
590
|
# File 'lib/vv/string_methods.rb', line 588
def cli_puts **kwargs
puts String.get_stdout { self.cli_print( **kwargs ) }
end
|
576
577
578
|
# File 'lib/vv/string_methods.rb', line 576
def eighth
self[7]
end
|
564
565
566
|
# File 'lib/vv/string_methods.rb', line 564
def fifth
self[4]
end
|
#file_join(*args) ⇒ Object
274
275
276
277
278
279
280
281
282
283
284
285
286
|
# File 'lib/vv/string_methods.rb', line 274
def file_join *args
unsafe = args.reject(&:safe_path?)
return File.join self, *args if unsafe.blank?
frags = unsafe.first(3).stringify_collection grave: true
count = unsafe.count
message = \
"#{count} unsafe path fragments including: #{frags}"
fail ArgumentError, message
end
|
#first(limit = 1) ⇒ Object
542
543
544
545
546
547
548
549
550
|
# File 'lib/vv/string_methods.rb', line 542
def first limit=1
if limit == 0
""
elsif limit >= size
dup
else
to(limit - 1)
end
end
|
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
|
# File 'lib/vv/string_methods.rb', line 191
def format!(other)
mappings = {}
self.split('#{')[1..-1].map do | token_fragment |
format_string = token_fragment.split("}").first
token = format_string.squish
value = other.instance_variable_get(token).to_s
wrapped_format_string = '#{' + format_string + "}"
mappings[wrapped_format_string] = value
end
response = self.dup
mappings.each do |key, value|
response.gsub! key, value
end
response
end
|
560
561
562
|
# File 'lib/vv/string_methods.rb', line 560
def fourth
self[3]
end
|
#from(position) ⇒ Object
462
463
464
|
# File 'lib/vv/string_methods.rb', line 462
def from position
self[position..-1]
end
|
#hex? ⇒ Boolean
288
289
290
291
292
|
# File 'lib/vv/string_methods.rb', line 288
def hex?
return false if self.blank?
match_non_hex_digits = /\H/
!self[match_non_hex_digits]
end
|
440
441
442
443
|
# File 'lib/vv/string_methods.rb', line 440
def insta
return self if self.starts_with?("@")
"@#{self}"
end
|
#insta_sym ⇒ Object
445
446
447
|
# File 'lib/vv/string_methods.rb', line 445
def insta_sym
self.insta.to_sym
end
|
#is_directory_path? ⇒ Boolean
266
267
268
|
# File 'lib/vv/string_methods.rb', line 266
def is_directory_path?
File.directory? self
end
|
#is_file_path? ⇒ Boolean
270
271
272
|
# File 'lib/vv/string_methods.rb', line 270
def is_file_path?
File.file? self
end
|
#last(limit = 1) ⇒ Object
532
533
534
535
536
537
538
539
540
|
# File 'lib/vv/string_methods.rb', line 532
def last(limit = 1)
if limit == 0
""
elsif limit >= size
self.dup
else
self.from(-limit)
end
end
|
#matches_glob(pattern) ⇒ Object
211
212
213
|
# File 'lib/vv/string_methods.rb', line 211
def matches_glob pattern
File.fnmatch(pattern, self)
end
|
580
581
582
|
# File 'lib/vv/string_methods.rb', line 580
def ninth
self[8]
end
|
#number? ⇒ Boolean
294
295
296
297
|
# File 'lib/vv/string_methods.rb', line 294
def number?
return false if self.blank?
self.gsub(/[^0-9]/, '') == self
end
|
#parse(notation: :json) ⇒ Object
324
325
326
327
328
329
|
# File 'lib/vv/string_methods.rb', line 324
def parse notation: :json
message = "Only JSON support at this time."
fail NotImplementedError, message unless notation == :json
::JSON.parse self
end
|
#parse_json ⇒ Object
331
332
333
|
# File 'lib/vv/string_methods.rb', line 331
def parse_json
self.parse notation: :json
end
|
#plural?(coward: true) ⇒ Boolean
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
|
# File 'lib/vv/string_methods.rb', line 478
def plural?(coward: true)
self._ensure_pluralize_available!
self._ensure_singularize_available!
plural = self == self.pluralize
return plural if !coward || !plural
non_ambiguous = self.pluralize != self.singularize
message = \
"String is ambiguously plural. Cowardly exiting."
raise RuntimeError, message unless non_ambiguous
true
end
|
#pop ⇒ Object
Also known as:
pop!
117
118
119
|
# File 'lib/vv/string_methods.rb', line 117
def pop
self.slice!(-1)
end
|
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
|
# File 'lib/vv/string_methods.rb', line 510
def query
string_fragments = self.split("#")[0].split("?")
message = "Query string contains multiple question marks"
fail message if string_fragments.count > 2
substring = string_fragments[-1]
response = {}
substring.split("&").each do |key_value_pair|
key, value = key_value_pair.split(String.equals_sign)
if key.ends_with? "[]"
_key = key[0..-3]
response[_key] ||= Array.new
response[_key] << value
else
response[key] = value
end
end
response
end
|
#readable_number? ⇒ Boolean
299
300
301
302
303
304
305
|
# File 'lib/vv/string_methods.rb', line 299
def readable_number?
self.readable_to_i
true
rescue StandardError => e
return false if e.message == "String is not a number"
raise
end
|
#readable_to_i ⇒ Object
366
367
368
369
370
371
372
373
374
375
376
377
|
# File 'lib/vv/string_methods.rb', line 366
def readable_to_i
return self.to_i if self.number?
valid_postfix = self._numeral_postfixes.include? self.last
valid_body = self[0...-1].number?
valid = valid_body && valid_postfix
message = "String is not a number"
raise StandardError, message unless valid
self[0...-1].to_i * self._numeral_postfixes[self.last]
end
|
#safe_dir_path?(allow_hidden: false, allow_absolute: true) ⇒ Boolean
252
253
254
255
256
257
258
259
260
261
262
263
264
|
# File 'lib/vv/string_methods.rb', line 252
def safe_dir_path? allow_hidden: false,
allow_absolute: true
separator = File::SEPARATOR
unsafe = false
unsafe ||= self.starts_with?(separator) unless allow_absolute
unsafe ||= self.after(separator, safe: false)
.split(separator).map do |fragment|
fragment.safe_filename? allow_hidden: allow_hidden
end.map(&:!).any?
! unsafe
end
|
#safe_filename?(allow_hidden: false) ⇒ Boolean
228
229
230
231
232
233
234
235
236
237
238
239
240
|
# File 'lib/vv/string_methods.rb', line 228
def safe_filename?( allow_hidden: false )
unsafe = self.blank?
unsafe ||= self.starts_with?(period) unless allow_hidden
unsafe ||= self.starts_with? dash
unsafe ||= self.end_with? period
unsafe ||= self.end_with? dash
unsafe ||= self =~ self.safe_filename_characters.to_regex_filter
! unsafe
end
|
#safe_path?(allow_hidden: false, allow_absolute: false) ⇒ Boolean
242
243
244
245
246
247
248
249
250
|
# File 'lib/vv/string_methods.rb', line 242
def safe_path?( allow_hidden: false, allow_absolute: false )
safe = self.safe_dir_path? allow_hidden: allow_hidden,
allow_absolute: allow_absolute
unsafe = ( ! safe )
unsafe ||= self.ends_with? File::SEPARATOR
! unsafe
end
|
552
553
554
|
# File 'lib/vv/string_methods.rb', line 552
def second
self[1]
end
|
449
450
451
452
|
# File 'lib/vv/string_methods.rb', line 449
def setter
return self if self.ends_with?(String.equals_sign)
"#{self}="
end
|
#setter_sym ⇒ Object
454
455
456
|
# File 'lib/vv/string_methods.rb', line 454
def setter_sym
self.setter.to_sym
end
|
572
573
574
|
# File 'lib/vv/string_methods.rb', line 572
def seventh
self[6]
end
|
#shift ⇒ Object
Also known as:
shift!
112
113
114
|
# File 'lib/vv/string_methods.rb', line 112
def shift
self.slice!(0)
end
|
#singular?(coward: true) ⇒ Boolean
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
|
# File 'lib/vv/string_methods.rb', line 494
def singular?(coward: true)
self._ensure_pluralize_available!
self._ensure_singularize_available!
singular = self == self.singularize
return singular if !coward || !singular
non_ambiguous = self.pluralize != self.singularize
message = \
"String is ambiguously singular. Cowardly exiting."
raise RuntimeError, message unless non_ambiguous
true
end
|
568
569
570
|
# File 'lib/vv/string_methods.rb', line 568
def sixth
self[5]
end
|
#split_english(ignore_newlines: false) ⇒ Object
168
169
170
171
172
173
174
175
176
177
178
|
# File 'lib/vv/string_methods.rb', line 168
def split_english ignore_newlines: false
options = [ ", ",
", and ",
", or ",
" and ",
" or "]
self.split_via(options,
ignore_newlines: ignore_newlines)
.map(&:strip)
end
|
#split_via(*arguments, ignore_newlines: false) ⇒ Object
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
# File 'lib/vv/string_methods.rb', line 141
def split_via *arguments, ignore_newlines: false
newlines_encountered = self.include? String.newline
newlines_ok = ( not newlines_encountered )
newlines_ok ||= ignore_newlines
message = "Newlines encountered, but disallowed. "
message += \
"Set `ignore_newlines` to true to treat as spaces."
fail message unless newlines_ok
args = arguments.flatten.sort_by(&:length).reverse
response = [self.gsub(String.newline, String.space)]
args.map do |arg|
response.map! do |fragment|
fragment.split arg
end
response.flatten!
end
response
end
|
187
188
189
|
# File 'lib/vv/string_methods.rb', line 187
def squish
self.dup.squish!
end
|
180
181
182
183
184
185
|
# File 'lib/vv/string_methods.rb', line 180
def squish!
self.gsub!(/\A[[:space:]]+/, "")
self.gsub!(/[[:space:]]+\z/, "")
self.gsub!(/[[:space:]]+/, " ")
self
end
|
#style(*args) ⇒ Object
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
|
# File 'lib/vv/string_methods.rb', line 397
def style *args
color = bold = underline = italic = nil
args.flatten!
args.map! { |arg| arg.to_sym }
args.each do |arg|
if Color.known_color? arg
if color.present?
raise "Color already set"
else
color = Color.new arg
end
elsif arg == :bold
bold = Bold.new
elsif arg == :underline
underline = Underline.new
elsif ( arg == :italic ) or ( arg == :italics )
italic = Italic.new
else
raise NotImplemented
end
end
reset = Format.reset_code
response = self.chomp(reset) + reset
response.prepend italic.code if italic
response.prepend underline.code if underline
response.prepend bold.code if bold
if color
start = response.index color.start_code
if start
finish = response[start..-1].index("m") + start
response.slice! start..finish
end
response.prepend color.code
end
response
end
|
584
585
586
|
# File 'lib/vv/string_methods.rb', line 584
def tenth
self[9]
end
|
556
557
558
|
# File 'lib/vv/string_methods.rb', line 556
def third
self[2]
end
|
#to(position) ⇒ Object
458
459
460
|
# File 'lib/vv/string_methods.rb', line 458
def to position
self[0..position]
end
|
#to_boolean ⇒ Object
307
308
309
310
311
312
313
314
315
316
317
318
|
# File 'lib/vv/string_methods.rb', line 307
def to_boolean
_true = self == "true"
return true if _true
_false = self == "false"
return false if _false
message = %w[ Unable to cast supplied string to boolean,
only `"true"` and `"false"` can be coerced into
boolean. ].spaced
raise RuntimeError, message
end
|
#to_h(parse: :json, symbolize_keys: false) ⇒ Object
347
348
349
350
351
352
353
354
355
356
357
358
359
360
|
# File 'lib/vv/string_methods.rb', line 347
def to_h parse: :json, symbolize_keys: false
message = "Only JSON support at this time."
fail NotImplementedError, message unless parse == :json
response = self.parse_json
response.symbolize_keys! if symbolize_keys
return response if response.to_h == response
message = \
"Parse string was #{response.class}, instead of Hash."
fail message
end
|
362
363
364
|
# File 'lib/vv/string_methods.rb', line 362
def to_i!
Integer(self)
end
|
215
216
217
|
# File 'lib/vv/string_methods.rb', line 215
def to_regex
Regexp.new self
end
|
#to_regex_filter ⇒ Object
219
220
221
222
|
# File 'lib/vv/string_methods.rb', line 219
def to_regex_filter
regex_string = '[^' + self + ']'
regex_string.to_regex
end
|
#to_regexp_filter ⇒ Object
224
225
226
|
# File 'lib/vv/string_methods.rb', line 224
def to_regexp_filter
self.to_regex_filter
end
|
335
336
337
338
339
340
341
342
343
344
345
|
# File 'lib/vv/string_methods.rb', line 335
def to_time
message = "Incorrect time string formatting `#{self}`, " + \
"must be of the form `2020-02-20T11:22:33.4567Z`"
fail message unless self.ends_with? "Z"
fail message unless self.split(String.dash).count == 3
fail message unless self.split(String.colon).count == 3
fail message unless self[10] == "T"
Time.parse self
end
|
#unstyle ⇒ Object
Also known as:
unstyled
386
387
388
389
|
# File 'lib/vv/string_methods.rb', line 386
def unstyle
self.gsub( /\e\[+\d+m/, empty_string )
.gsub( /\e\[((\d+)+\;)+\d+m/, empty_string )
end
|
392
393
394
395
|
# File 'lib/vv/string_methods.rb', line 392
def unstyle!
self.gsub!( /\e\[+\d+m/, empty_string )
self.gsub!( /\e\[((\d+)+\;)+\dm/, empty_string )
end
|
320
321
322
|
# File 'lib/vv/string_methods.rb', line 320
def vv_json
VV::JSON.generate self
end
|
#with_ending(string) ⇒ Object
133
134
135
|
# File 'lib/vv/string_methods.rb', line 133
def with_ending(string)
self.chomp(string) + string
end
|
#with_newline ⇒ Object
137
138
139
|
# File 'lib/vv/string_methods.rb', line 137
def with_newline
self.with_ending newline
end
|