sleeping_king_studios-tools 0.7.0 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|