sleeping_king_studios-tools 0.7.0 → 1.0.2
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +54 -3
- data/CODE_OF_CONDUCT.md +132 -0
- data/DEVELOPMENT.md +7 -16
- data/LICENSE +1 -1
- data/README.md +71 -145
- data/lib/sleeping_king_studios/tools.rb +12 -6
- data/lib/sleeping_king_studios/tools/array_tools.rb +86 -58
- data/lib/sleeping_king_studios/tools/base.rb +20 -0
- data/lib/sleeping_king_studios/tools/core_tools.rb +78 -19
- data/lib/sleeping_king_studios/tools/hash_tools.rb +69 -42
- data/lib/sleeping_king_studios/tools/integer_tools.rb +97 -55
- data/lib/sleeping_king_studios/tools/object_tools.rb +75 -52
- data/lib/sleeping_king_studios/tools/string_tools.rb +69 -96
- data/lib/sleeping_king_studios/tools/toolbelt.rb +44 -23
- data/lib/sleeping_king_studios/tools/toolbox.rb +2 -2
- data/lib/sleeping_king_studios/tools/toolbox/constant_map.rb +75 -74
- data/lib/sleeping_king_studios/tools/toolbox/inflector.rb +124 -0
- data/lib/sleeping_king_studios/tools/toolbox/inflector/rules.rb +173 -0
- data/lib/sleeping_king_studios/tools/toolbox/mixin.rb +11 -11
- data/lib/sleeping_king_studios/tools/toolbox/semantic_version.rb +15 -14
- data/lib/sleeping_king_studios/tools/version.rb +14 -10
- metadata +106 -35
- data/lib/sleeping_king_studios/tools/all.rb +0 -5
- data/lib/sleeping_king_studios/tools/enumerable_tools.rb +0 -8
- data/lib/sleeping_king_studios/tools/semantic_version.rb +0 -15
- data/lib/sleeping_king_studios/tools/string_tools/plural_inflector.rb +0 -185
- data/lib/sleeping_king_studios/tools/toolbox/configuration.rb +0 -207
- data/lib/sleeping_king_studios/tools/toolbox/delegator.rb +0 -175
@@ -1,19 +1,63 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'sleeping_king_studios/tools'
|
4
|
-
require 'sleeping_king_studios/tools/string_tools'
|
5
4
|
|
6
5
|
module SleepingKingStudios::Tools
|
7
6
|
# Tools for working with integers.
|
8
|
-
|
9
|
-
extend self
|
10
|
-
|
7
|
+
class IntegerTools < SleepingKingStudios::Tools::Base
|
11
8
|
# Minimum integer value that can be converted to a roman numeral.
|
12
9
|
ROMANIZE_MIN = 1
|
13
10
|
|
14
11
|
# Maximum integer value that can be converted to a roman numeral.
|
15
12
|
ROMANIZE_MAX = 4999
|
16
13
|
|
14
|
+
ROMANIZE_NUMERALS = [
|
15
|
+
%w[I V X].freeze,
|
16
|
+
%w[X L C].freeze,
|
17
|
+
%w[C D M].freeze,
|
18
|
+
['M', 'MMM', ''].freeze
|
19
|
+
].freeze
|
20
|
+
private_constant :ROMANIZE_NUMERALS
|
21
|
+
|
22
|
+
ROMANIZE_RULES = [
|
23
|
+
'',
|
24
|
+
'1',
|
25
|
+
'11',
|
26
|
+
'111',
|
27
|
+
'15',
|
28
|
+
'5',
|
29
|
+
'51',
|
30
|
+
'511',
|
31
|
+
'5111',
|
32
|
+
'1a',
|
33
|
+
'a'
|
34
|
+
].freeze
|
35
|
+
private_constant :ROMANIZE_RULES
|
36
|
+
|
37
|
+
ROMANIZE_RULES_ADDITIVE = [
|
38
|
+
'',
|
39
|
+
'1',
|
40
|
+
'11',
|
41
|
+
'111',
|
42
|
+
'1111',
|
43
|
+
'5',
|
44
|
+
'51',
|
45
|
+
'511',
|
46
|
+
'5111',
|
47
|
+
'51111',
|
48
|
+
'a'
|
49
|
+
].freeze
|
50
|
+
private_constant :ROMANIZE_RULES_ADDITIVE
|
51
|
+
|
52
|
+
class << self
|
53
|
+
def_delegators :instance,
|
54
|
+
:count_digits,
|
55
|
+
:digits,
|
56
|
+
:integer?,
|
57
|
+
:pluralize,
|
58
|
+
:romanize
|
59
|
+
end
|
60
|
+
|
17
61
|
# Returns the number of digits in the given integer when represented in the
|
18
62
|
# specified base. Ignores minus sign for negative numbers.
|
19
63
|
#
|
@@ -38,9 +82,9 @@ module SleepingKingStudios::Tools
|
|
38
82
|
# Defaults to 10.
|
39
83
|
#
|
40
84
|
# @return [Integer] The number of digits.
|
41
|
-
def count_digits
|
42
|
-
digits(integer.abs, :
|
43
|
-
end
|
85
|
+
def count_digits(integer, base: 10)
|
86
|
+
digits(integer.abs, base: base).count
|
87
|
+
end
|
44
88
|
|
45
89
|
# Decomposes the given integer into its digits when represented in the
|
46
90
|
# given base.
|
@@ -63,18 +107,18 @@ module SleepingKingStudios::Tools
|
|
63
107
|
#
|
64
108
|
# @return [Array<String>] The digits of the decomposed integer,
|
65
109
|
# represented as a bigendian array of strings.
|
66
|
-
def digits
|
110
|
+
def digits(integer, base: 10)
|
67
111
|
integer.to_s(base).split('')
|
68
|
-
end
|
112
|
+
end
|
69
113
|
|
70
114
|
# Returns true if the object is an Integer.
|
71
115
|
#
|
72
116
|
# @param int [Object] The object to test.
|
73
117
|
#
|
74
118
|
# @return [Boolean] True if the object is an Integer, otherwise false.
|
75
|
-
def integer?
|
76
|
-
Integer
|
77
|
-
end
|
119
|
+
def integer?(int)
|
120
|
+
int.is_a?(Integer)
|
121
|
+
end
|
78
122
|
|
79
123
|
# Returns the singular or the plural value, depending on the provided
|
80
124
|
# item count.
|
@@ -89,11 +133,11 @@ module SleepingKingStudios::Tools
|
|
89
133
|
#
|
90
134
|
# @return [String] The single form if count == 1; otherwise the plural
|
91
135
|
# form.
|
92
|
-
def pluralize
|
136
|
+
def pluralize(count, single, plural = nil)
|
93
137
|
plural ||= StringTools.pluralize(single)
|
94
138
|
|
95
|
-
|
96
|
-
end
|
139
|
+
count == 1 ? single : plural
|
140
|
+
end
|
97
141
|
|
98
142
|
# Represents an integer between 1 and 4999 (inclusive) as a Roman numeral.
|
99
143
|
#
|
@@ -114,42 +158,40 @@ module SleepingKingStudios::Tools
|
|
114
158
|
# @return [String] The representation of the integer as a Roman numeral.
|
115
159
|
#
|
116
160
|
# @raise [RangeError] If the integer is less than 1 or greater than 4999.
|
117
|
-
def romanize
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
]
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
end # module
|
155
|
-
end # module
|
161
|
+
def romanize(integer, additive: false)
|
162
|
+
check_romanize_range(integer)
|
163
|
+
|
164
|
+
digits(integer)
|
165
|
+
.reverse
|
166
|
+
.map
|
167
|
+
.with_index do |digit, index|
|
168
|
+
romanize_digit(additive: additive, digit: digit.to_i, tens: index)
|
169
|
+
end
|
170
|
+
.reverse
|
171
|
+
.join
|
172
|
+
end
|
173
|
+
|
174
|
+
private
|
175
|
+
|
176
|
+
def check_romanize_range(integer)
|
177
|
+
return if (ROMANIZE_MIN..ROMANIZE_MAX).include?(integer)
|
178
|
+
|
179
|
+
error_message =
|
180
|
+
"integer to romanize must be within range #{ROMANIZE_MIN} to" \
|
181
|
+
" #{ROMANIZE_MAX}"
|
182
|
+
|
183
|
+
raise RangeError, error_message, caller(1..-1)
|
184
|
+
end
|
185
|
+
|
186
|
+
def romanize_digit(additive:, digit:, tens:)
|
187
|
+
rules = (additive ? ROMANIZE_RULES_ADDITIVE : ROMANIZE_RULES)
|
188
|
+
rule = rules[digit]
|
189
|
+
numerals = ROMANIZE_NUMERALS[tens]
|
190
|
+
|
191
|
+
rule
|
192
|
+
.gsub('1', numerals[0])
|
193
|
+
.gsub('5', numerals[1])
|
194
|
+
.gsub('a', numerals[2])
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
@@ -1,16 +1,32 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'sleeping_king_studios/tools'
|
4
4
|
|
5
5
|
module SleepingKingStudios::Tools
|
6
6
|
# Low-level tools for working with objects.
|
7
|
-
|
8
|
-
|
7
|
+
class ObjectTools < SleepingKingStudios::Tools::Base
|
8
|
+
TEMPORARY_METHOD_NAME =
|
9
|
+
'__sleeping_king_studios_tools_apply_%i__'
|
10
|
+
private_constant :TEMPORARY_METHOD_NAME
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def_delegators :instance,
|
14
|
+
:apply,
|
15
|
+
:deep_dup,
|
16
|
+
:deep_freeze,
|
17
|
+
:dig,
|
18
|
+
:eigenclass,
|
19
|
+
:immutable?,
|
20
|
+
:metaclass,
|
21
|
+
:mutable?,
|
22
|
+
:object?,
|
23
|
+
:try
|
24
|
+
end
|
9
25
|
|
10
26
|
# Takes a proc or lambda and invokes it with the given object as
|
11
27
|
# receiver, with any additional arguments or block provided.
|
12
28
|
#
|
13
|
-
# @param [Object]
|
29
|
+
# @param [Object] receiver The receiver. The proc will be called in the
|
14
30
|
# context of this object.
|
15
31
|
# @param [Proc] proc The proc or lambda to call.
|
16
32
|
# @param [Array] args Optional. Additional arguments to pass in to the
|
@@ -20,20 +36,16 @@ module SleepingKingStudios::Tools
|
|
20
36
|
#
|
21
37
|
# @return The result of calling the proc or lambda with the given
|
22
38
|
# receiver and any additional arguments or block.
|
23
|
-
def apply
|
24
|
-
return
|
39
|
+
def apply(receiver, proc, *args, &block)
|
40
|
+
return receiver.instance_exec(*args, &proc) unless block_given?
|
25
41
|
|
26
|
-
|
42
|
+
method_name =
|
43
|
+
Kernel.format(TEMPORARY_METHOD_NAME, Thread.current.object_id)
|
27
44
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
begin
|
32
|
-
base.send temporary_method_name, *args, &block
|
33
|
-
ensure
|
34
|
-
metaclass.send :remove_method, temporary_method_name if temporary_method_name && defined?(temporary_method_name)
|
45
|
+
with_temporary_method(receiver, method_name, proc) do
|
46
|
+
receiver.send(method_name, *args, &block)
|
35
47
|
end
|
36
|
-
end
|
48
|
+
end
|
37
49
|
|
38
50
|
# Creates a deep copy of the object. If the object is an Array, returns a
|
39
51
|
# new Array with deep copies of each array item. If the object is a Hash,
|
@@ -43,7 +55,7 @@ module SleepingKingStudios::Tools
|
|
43
55
|
# @param [Object] obj The object to copy.
|
44
56
|
#
|
45
57
|
# @return The copy of the object.
|
46
|
-
def deep_dup
|
58
|
+
def deep_dup(obj)
|
47
59
|
case obj
|
48
60
|
when FalseClass, Integer, Float, NilClass, Symbol, TrueClass
|
49
61
|
obj
|
@@ -53,8 +65,8 @@ module SleepingKingStudios::Tools
|
|
53
65
|
HashTools.deep_dup obj
|
54
66
|
else
|
55
67
|
obj.respond_to?(:deep_dup) ? obj.deep_dup : obj.dup
|
56
|
-
end
|
57
|
-
end
|
68
|
+
end
|
69
|
+
end
|
58
70
|
|
59
71
|
# Performs a deep freeze of the object. If the object is an Array, freezes
|
60
72
|
# the array and performs a deep freeze on each array item. If the object is
|
@@ -62,7 +74,7 @@ module SleepingKingStudios::Tools
|
|
62
74
|
# value. Otherwise, calls Object#freeze.
|
63
75
|
#
|
64
76
|
# @param [Object] obj The object to freeze.
|
65
|
-
def deep_freeze
|
77
|
+
def deep_freeze(obj)
|
66
78
|
case obj
|
67
79
|
when FalseClass, Integer, Float, NilClass, Symbol, TrueClass
|
68
80
|
# Object is inherently immutable; do nothing here.
|
@@ -72,34 +84,41 @@ module SleepingKingStudios::Tools
|
|
72
84
|
HashTools.deep_freeze obj
|
73
85
|
else
|
74
86
|
obj.respond_to?(:deep_freeze) ? obj.deep_freeze : obj.freeze
|
75
|
-
end
|
76
|
-
end
|
87
|
+
end
|
88
|
+
end
|
77
89
|
|
78
90
|
# Accesses deeply nested attributes by calling the first named method on the
|
79
91
|
# given object, and each subsequent method on the result of the previous
|
80
92
|
# method call. If the object does not respond to the method name, nil is
|
81
93
|
# returned instead of calling the method.
|
82
94
|
#
|
83
|
-
# @param [Object]
|
95
|
+
# @param [Object] object The object to dig.
|
84
96
|
# @param [Array] method_names The names of the methods to call.
|
85
97
|
#
|
86
98
|
# @return [Object] The result of the last method call, or nil if the last
|
87
99
|
# object does not respond to the last method.
|
88
|
-
def dig
|
100
|
+
def dig(object, *method_names)
|
89
101
|
method_names.reduce(object) do |memo, method_name|
|
90
102
|
memo.respond_to?(method_name) ? memo.send(method_name) : nil
|
91
|
-
end
|
92
|
-
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# @!method metaclass(object)
|
107
|
+
# Returns the object's singleton class.
|
108
|
+
#
|
109
|
+
# @param [Object] object The object for which an eigenclass is required.
|
110
|
+
#
|
111
|
+
# @return [Class] The object's eigenclass.
|
93
112
|
|
94
113
|
# Returns the object's eigenclass.
|
95
114
|
#
|
96
115
|
# @param [Object] object The object for which an eigenclass is required.
|
97
116
|
#
|
98
|
-
# @return [Class] The object's
|
99
|
-
def eigenclass
|
100
|
-
|
101
|
-
end
|
102
|
-
|
117
|
+
# @return [Class] The object's singleton class.
|
118
|
+
def eigenclass(object)
|
119
|
+
object.singleton_class
|
120
|
+
end
|
121
|
+
alias metaclass eigenclass
|
103
122
|
|
104
123
|
# Returns true if the object is immutable. Values of nil, false, and true
|
105
124
|
# are always immutable, as are instances of Numeric and Symbol. Arrays are
|
@@ -110,7 +129,7 @@ module SleepingKingStudios::Tools
|
|
110
129
|
# @param obj [Object] The object to test.
|
111
130
|
#
|
112
131
|
# @return [Boolean] True if the object is immutable, otherwise false.
|
113
|
-
def immutable?
|
132
|
+
def immutable?(obj)
|
114
133
|
case obj
|
115
134
|
when NilClass, FalseClass, TrueClass, Numeric, Symbol
|
116
135
|
true
|
@@ -120,8 +139,8 @@ module SleepingKingStudios::Tools
|
|
120
139
|
HashTools.immutable? obj
|
121
140
|
else
|
122
141
|
obj.frozen?
|
123
|
-
end
|
124
|
-
end
|
142
|
+
end
|
143
|
+
end
|
125
144
|
|
126
145
|
# Returns true if the object is mutable.
|
127
146
|
#
|
@@ -130,9 +149,9 @@ module SleepingKingStudios::Tools
|
|
130
149
|
# @return [Boolean] True if the object is mutable, otherwise false.
|
131
150
|
#
|
132
151
|
# @see #immutable?
|
133
|
-
def mutable?
|
152
|
+
def mutable?(obj)
|
134
153
|
!immutable?(obj)
|
135
|
-
end
|
154
|
+
end
|
136
155
|
|
137
156
|
# Returns true if the object is an Object. This should return true only for
|
138
157
|
# objects that have an alternate inheritance chain from BasicObject, such as
|
@@ -141,9 +160,9 @@ module SleepingKingStudios::Tools
|
|
141
160
|
# @param obj [Object] The object to test.
|
142
161
|
#
|
143
162
|
# @return [Boolean] True if the object is an Object, otherwise false.
|
144
|
-
def object?
|
145
|
-
Object
|
146
|
-
end
|
163
|
+
def object?(obj)
|
164
|
+
Object.instance_method(:is_a?).bind(obj).call(Object)
|
165
|
+
end
|
147
166
|
|
148
167
|
# As #send, but returns nil if the object does not respond to the method.
|
149
168
|
#
|
@@ -151,23 +170,27 @@ module SleepingKingStudios::Tools
|
|
151
170
|
# @param [String, Symbol] method_name The name of the method to call.
|
152
171
|
# @param [Array] args The arguments to the message.
|
153
172
|
#
|
154
|
-
# @see
|
155
|
-
def try
|
156
|
-
if object.nil?
|
157
|
-
return object.respond_to?(method_name) ?
|
158
|
-
object.send(method_name, *args) :
|
159
|
-
nil
|
160
|
-
end # if
|
161
|
-
|
162
|
-
# Delegate to ActiveSupport::CoreExt::Object#try.
|
173
|
+
# @see ActiveSupport::CoreExt::Object#try.
|
174
|
+
def try(object, method_name, *args)
|
163
175
|
return object.try(method_name, *args) if object.respond_to?(:try)
|
164
176
|
|
177
|
+
return nil unless object.respond_to?(method_name)
|
178
|
+
|
165
179
|
object.send method_name, *args
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
180
|
+
end
|
181
|
+
|
182
|
+
private
|
183
|
+
|
184
|
+
def with_temporary_method(receiver, method_name, proc)
|
185
|
+
metaclass = class << receiver; self; end
|
186
|
+
metaclass.send :define_method, method_name, &proc
|
187
|
+
|
188
|
+
yield
|
189
|
+
ensure
|
190
|
+
metaclass.send :remove_method, method_name
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
171
194
|
|
172
195
|
require 'sleeping_king_studios/tools/array_tools'
|
173
196
|
require 'sleeping_king_studios/tools/hash_tools'
|
@@ -1,14 +1,40 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'sleeping_king_studios/tools'
|
4
|
-
require 'sleeping_king_studios/tools/
|
4
|
+
require 'sleeping_king_studios/tools/toolbox/inflector'
|
5
5
|
|
6
6
|
module SleepingKingStudios::Tools
|
7
7
|
# Tools for working with strings.
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
class StringTools < SleepingKingStudios::Tools::Base
|
9
|
+
class << self
|
10
|
+
def_delegators :instance,
|
11
|
+
:camelize,
|
12
|
+
:chain,
|
13
|
+
:define_irregular_word,
|
14
|
+
:define_plural_rule,
|
15
|
+
:define_singular_rule,
|
16
|
+
:define_uncountable_word,
|
17
|
+
:indent,
|
18
|
+
:map_lines,
|
19
|
+
:plural?,
|
20
|
+
:pluralize,
|
21
|
+
:singular?,
|
22
|
+
:singularize,
|
23
|
+
:string?,
|
24
|
+
:underscore
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param inflector [Object] An object that conforms to the interface used
|
28
|
+
# by SleepingKingStudios::Tools::Toolbox::Inflector, such as
|
29
|
+
# ActiveSupport::Inflector .
|
30
|
+
def initialize(inflector: nil)
|
31
|
+
super()
|
32
|
+
|
33
|
+
@inflector =
|
34
|
+
inflector || SleepingKingStudios::Tools::Toolbox::Inflector.new
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :inflector
|
12
38
|
|
13
39
|
# Converts a lowercase, underscore-separated string to CamelCase.
|
14
40
|
#
|
@@ -17,13 +43,11 @@ module SleepingKingStudios::Tools
|
|
17
43
|
# @return [String] The converted string.
|
18
44
|
#
|
19
45
|
# @see ActiveSupport::Inflector#camelize.
|
20
|
-
def camelize
|
46
|
+
def camelize(str)
|
21
47
|
str = require_string! str
|
22
48
|
|
23
|
-
str
|
24
|
-
|
25
|
-
str
|
26
|
-
end # method camelize
|
49
|
+
inflector.camelize(str)
|
50
|
+
end
|
27
51
|
|
28
52
|
# Performs multiple string tools operations in sequence, starting with the
|
29
53
|
# given string and passing the result of each operation to the next.
|
@@ -32,31 +56,11 @@ module SleepingKingStudios::Tools
|
|
32
56
|
# @param commands [Array<String, Symbol>] The string operations to apply.
|
33
57
|
#
|
34
58
|
# @return [String] The processed string.
|
35
|
-
def chain
|
59
|
+
def chain(str, *commands)
|
36
60
|
str = require_string! str
|
37
61
|
|
38
62
|
commands.reduce(str) { |memo, command| send(command, memo) }
|
39
|
-
end
|
40
|
-
|
41
|
-
# (see PluralInflector#define_irregular_word)
|
42
|
-
def define_irregular_word singular, plural
|
43
|
-
plural_inflector.define_irregular_word singular, plural
|
44
|
-
end # method define_irregular_word
|
45
|
-
|
46
|
-
# (see PluralInflector#define_plural_rule)
|
47
|
-
def define_plural_rule match, replace
|
48
|
-
plural_inflector.define_plural_rule match, replace
|
49
|
-
end # method define_plural_rule
|
50
|
-
|
51
|
-
# (see PluralInflector#define_singular_rule)
|
52
|
-
def define_singular_rule match, replace
|
53
|
-
plural_inflector.define_singular_rule match, replace
|
54
|
-
end # method define_singular_rule
|
55
|
-
|
56
|
-
# (see PluralInflector#define_uncountable_word)
|
57
|
-
def define_uncountable_word word
|
58
|
-
plural_inflector.define_uncountable_word word
|
59
|
-
end # method define_uncountable_word
|
63
|
+
end
|
60
64
|
|
61
65
|
# Adds the specified number of spaces to the start of each line of the
|
62
66
|
# string. Defaults to 2 spaces.
|
@@ -65,12 +69,12 @@ module SleepingKingStudios::Tools
|
|
65
69
|
# @param count [Integer] The number of spaces to add.
|
66
70
|
#
|
67
71
|
# @return [String] The indented string.
|
68
|
-
def indent
|
72
|
+
def indent(str, count = 2)
|
69
73
|
str = require_string! str
|
70
|
-
pre =
|
74
|
+
pre = ' ' * count
|
71
75
|
|
72
76
|
map_lines(str) { |line| "#{pre}#{line}" }
|
73
|
-
end
|
77
|
+
end
|
74
78
|
|
75
79
|
# Yields each line of the string to the provided block and combines the
|
76
80
|
# results into a new multiline string.
|
@@ -81,23 +85,23 @@ module SleepingKingStudios::Tools
|
|
81
85
|
# @yieldparam index [Integer] The index of the current line.
|
82
86
|
#
|
83
87
|
# @return [String] The mapped string.
|
84
|
-
def map_lines
|
88
|
+
def map_lines(str)
|
85
89
|
str = require_string! str
|
86
90
|
|
87
|
-
str.each_line.with_index.reduce('') do |memo, (line, index)|
|
91
|
+
str.each_line.with_index.reduce(+'') do |memo, (line, index)|
|
88
92
|
memo << yield(line, index)
|
89
|
-
end
|
90
|
-
end
|
93
|
+
end
|
94
|
+
end
|
91
95
|
|
92
96
|
# Determines whether or not the given word is in plural form. If calling
|
93
97
|
# #pluralize(word) is equal to word, the word is considered plural.
|
94
98
|
#
|
95
99
|
# @return [Boolean] True if the word is in plural form, otherwise false.
|
96
|
-
def plural?
|
100
|
+
def plural?(word)
|
97
101
|
word = require_string!(word)
|
98
102
|
|
99
103
|
word == pluralize(word)
|
100
|
-
end
|
104
|
+
end
|
101
105
|
|
102
106
|
# @overload pluralize(str)
|
103
107
|
# Takes a word in singular form and returns the plural form, based on the
|
@@ -106,63 +110,41 @@ module SleepingKingStudios::Tools
|
|
106
110
|
# @param str [String] The word to pluralize.
|
107
111
|
#
|
108
112
|
# @return [String] The pluralized word.
|
109
|
-
|
110
|
-
# @overload pluralize(count, single, plural)
|
111
|
-
# @deprecated This functionality is deprecated as of version 0.4.0 and
|
112
|
-
# will be removed in a future version. Use IntegerTools#pluralize
|
113
|
-
# instead.
|
114
|
-
#
|
115
|
-
# Returns the singular or the plural value, depending on the provided
|
116
|
-
# item count.
|
117
|
-
#
|
118
|
-
# @example
|
119
|
-
# "There are four #{StringTools.pluralize 4, 'light', 'lights'}!"
|
120
|
-
# #=> 'There are four lights!'
|
121
|
-
#
|
122
|
-
# @param [Integer] count The number of items.
|
123
|
-
# @param [String] single The singular form of the word or phrase.
|
124
|
-
# @param [String] plural The plural form of the word or phrase.
|
125
|
-
#
|
126
|
-
# @return [String] The single form if count == 1; otherwise the plural
|
127
|
-
# form.
|
128
|
-
def pluralize *args
|
129
|
-
if args.count == 3
|
130
|
-
CoreTools.deprecate 'StringTools#pluralize with 3 arguments',
|
131
|
-
:message => 'Use IntegerTools#pluralize instead.'
|
132
|
-
|
133
|
-
return IntegerTools.pluralize(*args)
|
134
|
-
end # if
|
135
|
-
|
113
|
+
def pluralize(*args)
|
136
114
|
str = require_string! args.first
|
137
115
|
|
138
|
-
|
139
|
-
end
|
116
|
+
inflector.pluralize str
|
117
|
+
end
|
140
118
|
|
141
119
|
# Determines whether or not the given word is in singular form. If calling
|
142
120
|
# #singularize(word) is equal to word, the word is considered singular.
|
143
121
|
#
|
144
122
|
# @return [Boolean] True if the word is in singular form, otherwise false.
|
145
|
-
def singular?
|
123
|
+
def singular?(word)
|
146
124
|
word = require_string!(word)
|
147
125
|
|
148
126
|
word == singularize(word)
|
149
|
-
end
|
127
|
+
end
|
150
128
|
|
151
|
-
#
|
152
|
-
|
129
|
+
# Transforms the word to a singular, lowercase form.
|
130
|
+
#
|
131
|
+
# @param str [String] The word to transform.
|
132
|
+
#
|
133
|
+
# @return [String] The word in singular form.
|
134
|
+
def singularize(str)
|
153
135
|
require_string! str
|
154
136
|
|
155
|
-
|
156
|
-
end
|
137
|
+
inflector.singularize str
|
138
|
+
end
|
157
139
|
|
158
140
|
# Returns true if the object is a String.
|
159
141
|
#
|
160
142
|
# @param str [Object] The object to test.
|
161
143
|
#
|
162
144
|
# @return [Boolean] True if the object is a String, otherwise false.
|
163
|
-
def string?
|
164
|
-
String
|
165
|
-
end
|
145
|
+
def string?(str)
|
146
|
+
str.is_a?(String)
|
147
|
+
end
|
166
148
|
|
167
149
|
# Converts a mixed-case string expression to a lowercase, underscore
|
168
150
|
# separated string.
|
@@ -172,29 +154,20 @@ module SleepingKingStudios::Tools
|
|
172
154
|
# @return [String] The converted string.
|
173
155
|
#
|
174
156
|
# @see ActiveSupport::Inflector#underscore.
|
175
|
-
def underscore
|
157
|
+
def underscore(str)
|
176
158
|
str = require_string! str
|
177
159
|
|
178
|
-
str
|
179
|
-
|
180
|
-
str.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
181
|
-
str.tr!("-", "_")
|
182
|
-
str.downcase!
|
183
|
-
str
|
184
|
-
end # method underscore
|
160
|
+
inflector.underscore(str)
|
161
|
+
end
|
185
162
|
|
186
163
|
private
|
187
164
|
|
188
|
-
def
|
189
|
-
@plural_inflector ||= PluralInflector.new
|
190
|
-
end # method plural_inflector
|
191
|
-
|
192
|
-
def require_string! value
|
165
|
+
def require_string!(value)
|
193
166
|
return value if string?(value)
|
194
167
|
|
195
168
|
return value.to_s if value.is_a?(Symbol)
|
196
169
|
|
197
170
|
raise ArgumentError, 'argument must be a string', caller[1..-1]
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|