hoodie 0.4.8 → 0.4.9
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 +4 -4
- data/lib/hoodie/inflections/defaults.rb +1 -1
- data/lib/hoodie/inflections/inflections.rb +155 -151
- data/lib/hoodie/inflections/rules_collection.rb +14 -12
- data/lib/hoodie/inflections.rb +146 -144
- data/lib/hoodie/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 78f652d3c64f70002f3a3b39648d94b5552e8802
|
|
4
|
+
data.tar.gz: 8639bdbefbb53ecae2be41440b6b3e2ed741e746
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7a665927fecac4819fddbf2e848f4cbd07742f3a02dcff18dd3f2a6c82ff66e550bfafa6b8cb345386925f8a903be3417c3bd7d5dd76a412a10b472afee77a45
|
|
7
|
+
data.tar.gz: d5d5c2293c27aadefceffdfde01ad1bb5e6a327150b2998fbd11965d182edb3b599303ab3f5403293183ed782490442bdb6aaae463d00b912746eb33f2bfd9bd
|
|
@@ -1,161 +1,165 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
|
|
3
|
-
module
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# Inflections.inflections do |inflect|
|
|
8
|
-
# inflect.plural /^(ox)$/i, '\1\2en'
|
|
9
|
-
# inflect.singular /^(ox)en/i, '\1'
|
|
10
|
-
#
|
|
11
|
-
# inflect.irregular 'octopus', 'octopi'
|
|
12
|
-
#
|
|
13
|
-
# inflect.uncountable "equipment"
|
|
14
|
-
# end
|
|
15
|
-
#
|
|
16
|
-
# New rules are added at the top. So in the example above, the irregular rule
|
|
17
|
-
# for octopus will now be the first of the pluralization and singularization
|
|
18
|
-
# rules that is runs. This guarantees that your rules run before any of the
|
|
19
|
-
# rules that may already have been loaded.
|
|
20
|
-
#
|
|
21
|
-
class Inflections
|
|
22
|
-
|
|
23
|
-
# Return instance
|
|
3
|
+
module Hoodie
|
|
4
|
+
module Inflections
|
|
5
|
+
# A singleton instance of this class is yielded by Inflections.inflections,
|
|
6
|
+
# which can then be used to specify additional inflection rules. Examples:
|
|
24
7
|
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
|
|
28
|
-
@__instance__ ||= new
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# @return [Array] plurals
|
|
32
|
-
# @api private
|
|
33
|
-
attr_reader :plurals
|
|
34
|
-
|
|
35
|
-
# @return [Array] singulars
|
|
36
|
-
# @api private
|
|
37
|
-
attr_reader :singulars
|
|
38
|
-
|
|
39
|
-
# @return [Array] uncountables
|
|
40
|
-
# @api private
|
|
41
|
-
attr_reader :uncountables
|
|
42
|
-
|
|
43
|
-
# @return [Array] humans
|
|
44
|
-
# @api private
|
|
45
|
-
attr_reader :humans
|
|
46
|
-
|
|
47
|
-
# Initialize object
|
|
48
|
-
#
|
|
49
|
-
# @return [undefined]
|
|
50
|
-
# @api private
|
|
51
|
-
def initialize
|
|
52
|
-
@plurals = RulesCollection.new
|
|
53
|
-
@singulars = RulesCollection.new
|
|
54
|
-
@humans = RulesCollection.new
|
|
55
|
-
@uncountables = Set[]
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Specifies a new pluralization rule and its replacement. The rule can
|
|
59
|
-
# either be a string or a regular expression. The replacement should always
|
|
60
|
-
# be a string that may include references to the matched data from the rule.
|
|
61
|
-
#
|
|
62
|
-
# @param [String, Regexp] rule
|
|
63
|
-
# @param [String, Regexp] replacement
|
|
64
|
-
# @return [self]
|
|
65
|
-
# @api private
|
|
66
|
-
def plural(rule, replacement)
|
|
67
|
-
rule(rule, replacement, @plurals)
|
|
68
|
-
self
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# Specifies a new singularization rule and its replacement. The rule can
|
|
72
|
-
# either be a string or a regular expression. The replacement should always
|
|
73
|
-
# be a string that may include references to the matched data from the rule.
|
|
74
|
-
#
|
|
75
|
-
# @param [String, Regexp] rule
|
|
76
|
-
# @param [String, Regexp] replacement
|
|
77
|
-
# @return [self]
|
|
78
|
-
# @api private
|
|
79
|
-
def singular(rule, replacement)
|
|
80
|
-
rule(rule, replacement, @singulars)
|
|
81
|
-
self
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Specifies a new irregular that applies to both pluralization and
|
|
85
|
-
# singularization at the same time. This can only be used for strings, not
|
|
86
|
-
# regular expressions. You simply pass the irregular in singular and plural
|
|
87
|
-
# form.
|
|
88
|
-
#
|
|
89
|
-
# @param [String] singular
|
|
90
|
-
# @param [String] plural
|
|
91
|
-
# @return [self]
|
|
92
|
-
# @api private
|
|
93
|
-
def irregular(singular, plural)
|
|
94
|
-
@uncountables.delete(singular)
|
|
95
|
-
@uncountables.delete(plural)
|
|
96
|
-
add_irregular(singular, plural, @plurals)
|
|
97
|
-
add_irregular(plural, singular, @singulars)
|
|
98
|
-
self
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
# Uncountable will not be inflected
|
|
102
|
-
#
|
|
103
|
-
# @param [Enumerable<String>] words
|
|
104
|
-
# @return [self]
|
|
105
|
-
# @api private
|
|
106
|
-
def uncountable(*words)
|
|
107
|
-
@uncountables.merge(words.flatten)
|
|
108
|
-
self
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
# Specifies a humanized form of a string by a regular expression rule or by
|
|
112
|
-
# a string mapping. When using a regular expression based replacement, the
|
|
113
|
-
# normal humanize formatting is called after the replacement. When a string
|
|
114
|
-
# is used, the human form should be specified as desired (example: 'The
|
|
115
|
-
# name', not 'the_name')
|
|
8
|
+
# Inflections.inflections do |inflect|
|
|
9
|
+
# inflect.plural /^(ox)$/i, '\1\2en'
|
|
10
|
+
# inflect.singular /^(ox)en/i, '\1'
|
|
116
11
|
#
|
|
117
|
-
#
|
|
118
|
-
# @param [String, Regexp] replacement
|
|
119
|
-
# @return [self]
|
|
120
|
-
# @api private
|
|
121
|
-
def human(rule, replacement)
|
|
122
|
-
@humans.insert(0, [rule, replacement])
|
|
123
|
-
self
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# Clear all inflection rules
|
|
12
|
+
# inflect.irregular 'octopus', 'octopi'
|
|
127
13
|
#
|
|
128
|
-
#
|
|
129
|
-
#
|
|
130
|
-
def clear
|
|
131
|
-
initialize
|
|
132
|
-
self
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
private
|
|
136
|
-
|
|
137
|
-
# Add irregular inflection
|
|
14
|
+
# inflect.uncountable "equipment"
|
|
15
|
+
# end
|
|
138
16
|
#
|
|
139
|
-
#
|
|
140
|
-
#
|
|
141
|
-
#
|
|
142
|
-
#
|
|
143
|
-
def add_irregular(rule, replacement, target)
|
|
144
|
-
head, *tail = rule.chars.to_a
|
|
145
|
-
rule(/(#{head})#{tail.join}\z/i, '\1' + replacement[1..-1], target)
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
# Add a new rule
|
|
17
|
+
# New rules are added at the top. So in the example above, the irregular
|
|
18
|
+
# rule for octopus will now be the first of the pluralization and
|
|
19
|
+
# singularization rules that is runs. This guarantees that your rules run
|
|
20
|
+
# before any of the rules that may already have been loaded.
|
|
149
21
|
#
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
22
|
+
class Inflections
|
|
23
|
+
|
|
24
|
+
# Return instance
|
|
25
|
+
#
|
|
26
|
+
# @return [Inflections]
|
|
27
|
+
# @api private
|
|
28
|
+
def self.instance
|
|
29
|
+
@__instance__ ||= new
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @return [Array] plurals
|
|
33
|
+
# @api private
|
|
34
|
+
attr_reader :plurals
|
|
35
|
+
|
|
36
|
+
# @return [Array] singulars
|
|
37
|
+
# @api private
|
|
38
|
+
attr_reader :singulars
|
|
39
|
+
|
|
40
|
+
# @return [Array] uncountables
|
|
41
|
+
# @api private
|
|
42
|
+
attr_reader :uncountables
|
|
43
|
+
|
|
44
|
+
# @return [Array] humans
|
|
45
|
+
# @api private
|
|
46
|
+
attr_reader :humans
|
|
47
|
+
|
|
48
|
+
# Initialize object
|
|
49
|
+
#
|
|
50
|
+
# @return [undefined]
|
|
51
|
+
# @api private
|
|
52
|
+
def initialize
|
|
53
|
+
@plurals = RulesCollection.new
|
|
54
|
+
@singulars = RulesCollection.new
|
|
55
|
+
@humans = RulesCollection.new
|
|
56
|
+
@uncountables = Set[]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Specifies a new pluralization rule and its replacement. The rule can
|
|
60
|
+
# either be a string or a regular expression. The replacement should
|
|
61
|
+
# always be a string that may include references to the matched data from
|
|
62
|
+
# the rule.
|
|
63
|
+
#
|
|
64
|
+
# @param [String, Regexp] rule
|
|
65
|
+
# @param [String, Regexp] replacement
|
|
66
|
+
# @return [self]
|
|
67
|
+
# @api private
|
|
68
|
+
def plural(rule, replacement)
|
|
69
|
+
rule(rule, replacement, @plurals)
|
|
70
|
+
self
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Specifies a new singularization rule and its replacement. The rule can
|
|
74
|
+
# either be a string or a regular expression. The replacement should
|
|
75
|
+
# always be a string that may include references to the matched data from
|
|
76
|
+
# the rule.
|
|
77
|
+
#
|
|
78
|
+
# @param [String, Regexp] rule
|
|
79
|
+
# @param [String, Regexp] replacement
|
|
80
|
+
# @return [self]
|
|
81
|
+
# @api private
|
|
82
|
+
def singular(rule, replacement)
|
|
83
|
+
rule(rule, replacement, @singulars)
|
|
84
|
+
self
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Specifies a new irregular that applies to both pluralization and
|
|
88
|
+
# singularization at the same time. This can only be used for strings, not
|
|
89
|
+
# regular expressions. You simply pass the irregular in singular and
|
|
90
|
+
# plural form.
|
|
91
|
+
#
|
|
92
|
+
# @param [String] singular
|
|
93
|
+
# @param [String] plural
|
|
94
|
+
# @return [self]
|
|
95
|
+
# @api private
|
|
96
|
+
def irregular(singular, plural)
|
|
97
|
+
@uncountables.delete(singular)
|
|
98
|
+
@uncountables.delete(plural)
|
|
99
|
+
add_irregular(singular, plural, @plurals)
|
|
100
|
+
add_irregular(plural, singular, @singulars)
|
|
101
|
+
self
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Uncountable will not be inflected
|
|
105
|
+
#
|
|
106
|
+
# @param [Enumerable<String>] words
|
|
107
|
+
# @return [self]
|
|
108
|
+
# @api private
|
|
109
|
+
def uncountable(*words)
|
|
110
|
+
@uncountables.merge(words.flatten)
|
|
111
|
+
self
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Specifies a humanized form of a string by a regular expression rule or
|
|
115
|
+
# by a string mapping. When using a regular expression based replacement,
|
|
116
|
+
# the normal humanize formatting is called after the replacement. When a
|
|
117
|
+
# string is used, the human form should be specified as desired (example:
|
|
118
|
+
# 'The name', not 'the_name')
|
|
119
|
+
#
|
|
120
|
+
# @param [String, Regexp] rule
|
|
121
|
+
# @param [String, Regexp] replacement
|
|
122
|
+
# @return [self]
|
|
123
|
+
# @api private
|
|
124
|
+
def human(rule, replacement)
|
|
125
|
+
@humans.insert(0, [rule, replacement])
|
|
126
|
+
self
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Clear all inflection rules
|
|
130
|
+
#
|
|
131
|
+
# @return [self]
|
|
132
|
+
# @api private
|
|
133
|
+
def clear
|
|
134
|
+
initialize
|
|
135
|
+
self
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
private
|
|
139
|
+
|
|
140
|
+
# Add irregular inflection
|
|
141
|
+
#
|
|
142
|
+
# @param [String] rule
|
|
143
|
+
# @param [String] replacement
|
|
144
|
+
# @return [undefined]
|
|
145
|
+
# @api private
|
|
146
|
+
def add_irregular(rule, replacement, target)
|
|
147
|
+
head, *tail = rule.chars.to_a
|
|
148
|
+
rule(/(#{head})#{tail.join}\z/i, '\1' + replacement[1..-1], target)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Add a new rule
|
|
152
|
+
#
|
|
153
|
+
# @param [String, Regexp] rule
|
|
154
|
+
# @param [String, Regexp] replacement
|
|
155
|
+
# @param [Array] target
|
|
156
|
+
# @return [undefined]
|
|
157
|
+
# @api private
|
|
158
|
+
def rule(rule, replacement, target)
|
|
159
|
+
@uncountables.delete(rule)
|
|
160
|
+
@uncountables.delete(replacement)
|
|
161
|
+
target.insert(0, [rule, replacement])
|
|
162
|
+
end
|
|
159
163
|
end
|
|
160
164
|
end
|
|
161
165
|
end
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
|
|
3
|
-
module
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class RulesCollection < Array
|
|
7
|
-
# Applies first found rule to given word
|
|
3
|
+
module Hoodie
|
|
4
|
+
module Inflections
|
|
5
|
+
# Wraps inflections array
|
|
8
6
|
#
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
class RulesCollection < Array
|
|
8
|
+
# Applies first found rule to given word
|
|
9
|
+
#
|
|
10
|
+
# @param [String] word
|
|
11
|
+
# @return [String] modified word
|
|
12
|
+
# @api private
|
|
13
|
+
def apply_to(word)
|
|
14
|
+
result = word.dup
|
|
15
|
+
each { |rule, replacement| break if result.gsub!(rule, replacement) }
|
|
16
|
+
result
|
|
17
|
+
end
|
|
16
18
|
end
|
|
17
19
|
end
|
|
18
20
|
end
|
data/lib/hoodie/inflections.rb
CHANGED
|
@@ -1,169 +1,171 @@
|
|
|
1
1
|
|
|
2
2
|
require 'set'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
module Inflections
|
|
10
|
-
|
|
11
|
-
# Convert input to UpperCamelCase. Will also convert '/' to '::' which is
|
|
12
|
-
# useful for converting paths to namespaces.
|
|
4
|
+
module Hoodie
|
|
5
|
+
# The Inflections transforms words from singular to plural, class names to
|
|
6
|
+
# table names, modularized class names to ones without, and class names to
|
|
7
|
+
# foreign keys. The default inflections for pluralization, singularization,
|
|
8
|
+
# and uncountable words are kept in inflections.rb.
|
|
13
9
|
#
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
module Inflections
|
|
11
|
+
|
|
12
|
+
# Convert input to UpperCamelCase. Will also convert '/' to '::' which is
|
|
13
|
+
# useful for converting paths to namespaces.
|
|
14
|
+
#
|
|
15
|
+
# @param [String] input
|
|
16
|
+
# @return [String]
|
|
17
|
+
def self.camelize(input)
|
|
18
|
+
input.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:\A|_)(.)/) { $1.upcase }
|
|
19
|
+
end
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
# Convert input to underscored, lowercase string. Changes '::' to '/' to
|
|
22
|
+
# convert namespaces to paths.
|
|
23
|
+
#
|
|
24
|
+
# @param [String] input
|
|
25
|
+
# @return [String]
|
|
26
|
+
def self.underscore(input)
|
|
27
|
+
word = input.gsub(/::/, '/')
|
|
28
|
+
underscorize(word)
|
|
29
|
+
end
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
# Convert input underscores to dashes.
|
|
32
|
+
#
|
|
33
|
+
# @param [String] input
|
|
34
|
+
# @return [String]
|
|
35
|
+
def self.dasherize(input)
|
|
36
|
+
input.tr('_', '-')
|
|
37
|
+
end
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
# Return unscoped constant name.
|
|
40
|
+
#
|
|
41
|
+
# @param [String] input
|
|
42
|
+
# @return [String]
|
|
43
|
+
def self.demodulize(input)
|
|
44
|
+
input.split('::').last
|
|
45
|
+
end
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
# Creates a foreign key name
|
|
48
|
+
#
|
|
49
|
+
# @param [String] input
|
|
50
|
+
# @return [String]
|
|
51
|
+
def self.foreign_key(input)
|
|
52
|
+
"#{underscorize(demodulize(input))}_id"
|
|
53
|
+
end
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
55
|
+
# Find a constant with the name specified in the argument string. The name
|
|
56
|
+
# is assumed to be the one of a top-level constant, constant scope of
|
|
57
|
+
# caller is igored.
|
|
58
|
+
#
|
|
59
|
+
# @param [String] input
|
|
60
|
+
# @return [Class, Module]
|
|
61
|
+
def self.constantize(input)
|
|
62
|
+
names = input.split('::')
|
|
63
|
+
names.shift if names.first.empty?
|
|
64
|
+
|
|
65
|
+
names.inject(Object) do |constant, name|
|
|
66
|
+
if constant.const_defined?(name)
|
|
67
|
+
constant.const_get(name)
|
|
68
|
+
else
|
|
69
|
+
constant.const_missing(name)
|
|
70
|
+
end
|
|
69
71
|
end
|
|
70
72
|
end
|
|
71
|
-
end
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
ORDINALIZE_TH = (4..16).to_set.freeze
|
|
74
75
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
76
|
+
# Convert a number into an ordinal string.
|
|
77
|
+
#
|
|
78
|
+
# @param [Fixnum] number
|
|
79
|
+
# @return [String]
|
|
80
|
+
def self.ordinalize(number)
|
|
81
|
+
abs_value = number.abs
|
|
82
|
+
|
|
83
|
+
if ORDINALIZE_TH.include?(abs_value % 100)
|
|
84
|
+
"#{number}th"
|
|
85
|
+
else
|
|
86
|
+
case abs_value % 10
|
|
87
|
+
when 1; "#{number}st"
|
|
88
|
+
when 2; "#{number}nd"
|
|
89
|
+
when 3; "#{number}rd"
|
|
90
|
+
end
|
|
89
91
|
end
|
|
90
92
|
end
|
|
91
|
-
end
|
|
92
93
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
# Convert word to singular
|
|
103
|
-
#
|
|
104
|
-
# @param [String] word
|
|
105
|
-
# @return [String]
|
|
106
|
-
def self.singularize(word)
|
|
107
|
-
return word if uncountable?(word)
|
|
108
|
-
inflections.singulars.apply_to(word)
|
|
109
|
-
end
|
|
94
|
+
# Convert input word string to plural
|
|
95
|
+
#
|
|
96
|
+
# @param [String] word
|
|
97
|
+
# @return [String]
|
|
98
|
+
def self.pluralize(word)
|
|
99
|
+
return word if uncountable?(word)
|
|
100
|
+
inflections.plurals.apply_to(word)
|
|
101
|
+
end
|
|
110
102
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
result.capitalize!
|
|
120
|
-
result
|
|
121
|
-
end
|
|
103
|
+
# Convert word to singular
|
|
104
|
+
#
|
|
105
|
+
# @param [String] word
|
|
106
|
+
# @return [String]
|
|
107
|
+
def self.singularize(word)
|
|
108
|
+
return word if uncountable?(word)
|
|
109
|
+
inflections.singulars.apply_to(word)
|
|
110
|
+
end
|
|
122
111
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
112
|
+
# Humanize string.
|
|
113
|
+
#
|
|
114
|
+
# @param [String] input
|
|
115
|
+
# @return [String]
|
|
116
|
+
def self.humanize(input)
|
|
117
|
+
result = inflections.humans.apply_to(input)
|
|
118
|
+
result.gsub!(/_id\z/, "")
|
|
119
|
+
result.tr!('_', " ")
|
|
120
|
+
result.capitalize!
|
|
121
|
+
result
|
|
122
|
+
end
|
|
130
123
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
end
|
|
124
|
+
# Tabelize input string.
|
|
125
|
+
#
|
|
126
|
+
# @param [String] input
|
|
127
|
+
# @return [String]
|
|
128
|
+
def self.tableize(input)
|
|
129
|
+
pluralize(underscore(input).gsub('/', '_'))
|
|
130
|
+
end
|
|
139
131
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
132
|
+
# Create a class name from a plural table name like Rails does for table
|
|
133
|
+
# names to models.
|
|
134
|
+
#
|
|
135
|
+
# @param [String] input
|
|
136
|
+
# @return [String]
|
|
137
|
+
def self.classify(table_name)
|
|
138
|
+
camelize(singularize(table_name.sub(/.*\./, '')))
|
|
139
|
+
end
|
|
147
140
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
word.tr!('-', '_')
|
|
156
|
-
word.downcase!
|
|
157
|
-
word
|
|
158
|
-
end
|
|
159
|
-
private_class_method :underscorize
|
|
141
|
+
# Test if word is uncountable.
|
|
142
|
+
#
|
|
143
|
+
# @param [String] word
|
|
144
|
+
# @return [Boolean] true, if word is uncountable
|
|
145
|
+
def self.uncountable?(word)
|
|
146
|
+
word.empty? || inflections.uncountables.include?(word.downcase)
|
|
147
|
+
end
|
|
160
148
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
149
|
+
# Convert input to underscored, lowercase string
|
|
150
|
+
#
|
|
151
|
+
# @param [String] input
|
|
152
|
+
# @return [String]
|
|
153
|
+
def self.underscorize(word)
|
|
154
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
|
155
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
|
156
|
+
word.tr!('-', '_')
|
|
157
|
+
word.downcase!
|
|
158
|
+
word
|
|
159
|
+
end
|
|
160
|
+
private_class_method :underscorize
|
|
161
|
+
|
|
162
|
+
# Yields a singleton instance of Inflecto::Inflections.
|
|
163
|
+
#
|
|
164
|
+
# @return [Inflections::Inflections]
|
|
165
|
+
def self.inflections
|
|
166
|
+
instance = Inflections.instance
|
|
167
|
+
block_given? ? yield(instance) : instance
|
|
168
|
+
end
|
|
167
169
|
end
|
|
168
170
|
end
|
|
169
171
|
|
data/lib/hoodie/version.rb
CHANGED