shattered_support 0.3.2 → 0.3.3
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.
- data/lib/shattered_support/core_ext/class/attribute_accessors.rb +44 -0
- data/lib/shattered_support/core_ext/class/inheritable_attributes.rb +115 -0
- data/lib/shattered_support/core_ext/class/removal.rb +24 -0
- data/lib/shattered_support/core_ext/class.rb +3 -0
- data/lib/shattered_support/core_ext/dir/search.rb +25 -0
- data/lib/shattered_support/core_ext/dir.rb +5 -0
- data/lib/shattered_support/core_ext/file/search.rb +50 -0
- data/lib/shattered_support/core_ext/file.rb +5 -0
- data/lib/shattered_support/core_ext/numeric/time.rb +72 -0
- data/lib/shattered_support/core_ext/numeric.rb +5 -0
- data/lib/shattered_support/core_ext/string/access.rb +58 -0
- data/lib/shattered_support/core_ext/string/conversions.rb +19 -0
- data/lib/shattered_support/core_ext/string/inflections.rb +64 -0
- data/lib/shattered_support/core_ext/string/iterators.rb +17 -0
- data/lib/shattered_support/core_ext/string/starts_ends_with.rb +20 -0
- data/lib/shattered_support/core_ext/string.rb +13 -0
- data/lib/shattered_support/core_ext.rb +1 -0
- data/lib/shattered_support/inflections.rb +53 -0
- data/lib/shattered_support/inflector.rb +178 -0
- data/lib/shattered_support.rb +2 -64
- metadata +38 -16
- data/lib/base.rb +0 -221
- data/lib/runner.rb +0 -11
- data/lib/timer/timed_event.rb +0 -77
- data/lib/timer/timer.rb +0 -67
- data/lib/vector.rb +0 -206
@@ -0,0 +1,44 @@
|
|
1
|
+
# Extends the class object with class and instance accessors for class attributes,
|
2
|
+
# just like the native attr* accessors for instance attributes.
|
3
|
+
class Class # :nodoc:
|
4
|
+
def cattr_reader(*syms)
|
5
|
+
syms.flatten.each do |sym|
|
6
|
+
class_eval(<<-EOS, __FILE__, __LINE__)
|
7
|
+
unless defined? @@#{sym}
|
8
|
+
@@#{sym} = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.#{sym}
|
12
|
+
@@#{sym}
|
13
|
+
end
|
14
|
+
|
15
|
+
def #{sym}
|
16
|
+
@@#{sym}
|
17
|
+
end
|
18
|
+
EOS
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def cattr_writer(*syms)
|
23
|
+
syms.flatten.each do |sym|
|
24
|
+
class_eval(<<-EOS, __FILE__, __LINE__)
|
25
|
+
unless defined? @@#{sym}
|
26
|
+
@@#{sym} = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.#{sym}=(obj)
|
30
|
+
@@#{sym} = obj
|
31
|
+
end
|
32
|
+
|
33
|
+
def #{sym}=(obj)
|
34
|
+
@@#{sym} = obj
|
35
|
+
end
|
36
|
+
EOS
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def cattr_accessor(*syms)
|
41
|
+
cattr_reader(*syms)
|
42
|
+
cattr_writer(*syms)
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# Retain for backward compatibility. Methods are now included in Class.
|
2
|
+
module ClassInheritableAttributes # :nodoc:
|
3
|
+
end
|
4
|
+
|
5
|
+
# Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
|
6
|
+
# their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
|
7
|
+
# to, for example, an array without those additions being shared with either their parent, siblings, or
|
8
|
+
# children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
|
9
|
+
class Class # :nodoc:
|
10
|
+
def class_inheritable_reader(*syms)
|
11
|
+
syms.each do |sym|
|
12
|
+
class_eval <<-EOS
|
13
|
+
def self.#{sym}
|
14
|
+
read_inheritable_attribute(:#{sym})
|
15
|
+
end
|
16
|
+
|
17
|
+
def #{sym}
|
18
|
+
self.class.#{sym}
|
19
|
+
end
|
20
|
+
EOS
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def class_inheritable_writer(*syms)
|
25
|
+
syms.each do |sym|
|
26
|
+
class_eval <<-EOS
|
27
|
+
def self.#{sym}=(obj)
|
28
|
+
write_inheritable_attribute(:#{sym}, obj)
|
29
|
+
end
|
30
|
+
|
31
|
+
def #{sym}=(obj)
|
32
|
+
self.class.#{sym} = obj
|
33
|
+
end
|
34
|
+
EOS
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def class_inheritable_array_writer(*syms)
|
39
|
+
syms.each do |sym|
|
40
|
+
class_eval <<-EOS
|
41
|
+
def self.#{sym}=(obj)
|
42
|
+
write_inheritable_array(:#{sym}, obj)
|
43
|
+
end
|
44
|
+
|
45
|
+
def #{sym}=(obj)
|
46
|
+
self.class.#{sym} = obj
|
47
|
+
end
|
48
|
+
EOS
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def class_inheritable_hash_writer(*syms)
|
53
|
+
syms.each do |sym|
|
54
|
+
class_eval <<-EOS
|
55
|
+
def self.#{sym}=(obj)
|
56
|
+
write_inheritable_hash(:#{sym}, obj)
|
57
|
+
end
|
58
|
+
|
59
|
+
def #{sym}=(obj)
|
60
|
+
self.class.#{sym} = obj
|
61
|
+
end
|
62
|
+
EOS
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def class_inheritable_accessor(*syms)
|
67
|
+
class_inheritable_reader(*syms)
|
68
|
+
class_inheritable_writer(*syms)
|
69
|
+
end
|
70
|
+
|
71
|
+
def class_inheritable_array(*syms)
|
72
|
+
class_inheritable_reader(*syms)
|
73
|
+
class_inheritable_array_writer(*syms)
|
74
|
+
end
|
75
|
+
|
76
|
+
def class_inheritable_hash(*syms)
|
77
|
+
class_inheritable_reader(*syms)
|
78
|
+
class_inheritable_hash_writer(*syms)
|
79
|
+
end
|
80
|
+
|
81
|
+
def inheritable_attributes
|
82
|
+
@inheritable_attributes ||= {}
|
83
|
+
end
|
84
|
+
|
85
|
+
def write_inheritable_attribute(key, value)
|
86
|
+
inheritable_attributes[key] = value
|
87
|
+
end
|
88
|
+
|
89
|
+
def write_inheritable_array(key, elements)
|
90
|
+
write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
|
91
|
+
write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
|
92
|
+
end
|
93
|
+
|
94
|
+
def write_inheritable_hash(key, hash)
|
95
|
+
write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
|
96
|
+
write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
|
97
|
+
end
|
98
|
+
|
99
|
+
def read_inheritable_attribute(key)
|
100
|
+
inheritable_attributes[key]
|
101
|
+
end
|
102
|
+
|
103
|
+
def reset_inheritable_attributes
|
104
|
+
inheritable_attributes.clear
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
def inherited_with_inheritable_attributes(child)
|
109
|
+
inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes)
|
110
|
+
child.instance_variable_set('@inheritable_attributes', inheritable_attributes.dup)
|
111
|
+
end
|
112
|
+
|
113
|
+
alias inherited_without_inheritable_attributes inherited
|
114
|
+
alias inherited inherited_with_inheritable_attributes
|
115
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Class #:nodoc:
|
2
|
+
def remove_subclasses
|
3
|
+
Object.remove_subclasses_of(self)
|
4
|
+
end
|
5
|
+
|
6
|
+
def subclasses
|
7
|
+
Object.subclasses_of(self).map { |o| o.to_s }
|
8
|
+
end
|
9
|
+
|
10
|
+
def remove_class(*klasses)
|
11
|
+
klasses.flatten.each do |klass|
|
12
|
+
# Skip this class if there is nothing bound to this name
|
13
|
+
next unless defined?(klass.name)
|
14
|
+
|
15
|
+
basename = klass.to_s.split("::").last
|
16
|
+
parent = klass.parent
|
17
|
+
|
18
|
+
# Skip this class if it does not match the current one bound to this name
|
19
|
+
next unless parent.const_defined?(basename) && klass = parent.const_get(basename)
|
20
|
+
|
21
|
+
parent.send :remove_const, basename unless parent == klass
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module ShatteredSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Dir #:nodoc:
|
4
|
+
module Search #:nodoc:
|
5
|
+
def self.append_features(base) #:nodoc:
|
6
|
+
super
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Dir.each_in_path will recursively yield all non-hidden
|
11
|
+
# directories from the given path.
|
12
|
+
module ClassMethods
|
13
|
+
def each_in_path(path, &block)
|
14
|
+
return unless ::File.directory? path
|
15
|
+
yield path
|
16
|
+
foreach(path) do |directory|
|
17
|
+
next if directory =~ /\..*/
|
18
|
+
each_in_path("#{path}/#{directory}", &block)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module ShatteredSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module File #:nodoc:
|
4
|
+
module Search #:nodoc:
|
5
|
+
def self.append_features(base) #:nodoc:
|
6
|
+
super
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
# File.each_in_path will recursively look for all files,
|
12
|
+
# starting at the given path.
|
13
|
+
# It will yield with each result.
|
14
|
+
def each_in_path(path)
|
15
|
+
::Dir.each_in_path(path) do |directory|
|
16
|
+
::Dir.foreach( directory ) do |filename|
|
17
|
+
resource = directory + "/#{filename}"
|
18
|
+
yield(resource) if ::File.file? resource
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# This finds all files in paths (an array or string)
|
24
|
+
# matching the given extensions:
|
25
|
+
#
|
26
|
+
# Usage:
|
27
|
+
# -File.find_by_extensions(SHATTERED_ROOT,"ogg","mp3","wav")
|
28
|
+
# -File.find_by_extension(["apps","media","plugins"], "rmaterial")
|
29
|
+
def find_by_extensions(paths, *extensions)
|
30
|
+
paths = [paths] if paths.is_a? ::String
|
31
|
+
# get rid of "." in ".ogg"
|
32
|
+
extensions.collect! { |ext| ext[0].chr == "." ? ext[1..-1] : ext }
|
33
|
+
reg_exp = /\.(#{extensions.join("|")})$/
|
34
|
+
files = []
|
35
|
+
paths.each do |path|
|
36
|
+
each_in_path(path) do |filename|
|
37
|
+
files << filename if filename =~ reg_exp
|
38
|
+
end
|
39
|
+
end
|
40
|
+
return files
|
41
|
+
end
|
42
|
+
# See File#find_by_extensions
|
43
|
+
def find_by_extension(paths, extension)
|
44
|
+
find_by_extensions(paths, extension)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module ShatteredSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Numeric #:nodoc:
|
4
|
+
# Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
|
5
|
+
#
|
6
|
+
# If you need precise date calculations that doesn't just treat months as 30 days, then have
|
7
|
+
# a look at Time#advance.
|
8
|
+
#
|
9
|
+
# Some of these methods are approximations, Ruby's core
|
10
|
+
# Date[http://stdlib.rubyonrails.org/libdoc/date/rdoc/index.html] and
|
11
|
+
# Time[http://stdlib.rubyonrails.org/libdoc/time/rdoc/index.html] should be used for precision
|
12
|
+
# date and time arithmetic
|
13
|
+
module Time
|
14
|
+
def seconds
|
15
|
+
self
|
16
|
+
end
|
17
|
+
alias :second :seconds
|
18
|
+
|
19
|
+
def minutes
|
20
|
+
self * 60
|
21
|
+
end
|
22
|
+
alias :minute :minutes
|
23
|
+
|
24
|
+
def hours
|
25
|
+
self * 60.minutes
|
26
|
+
end
|
27
|
+
alias :hour :hours
|
28
|
+
|
29
|
+
def days
|
30
|
+
self * 24.hours
|
31
|
+
end
|
32
|
+
alias :day :days
|
33
|
+
|
34
|
+
def weeks
|
35
|
+
self * 7.days
|
36
|
+
end
|
37
|
+
alias :week :weeks
|
38
|
+
|
39
|
+
def fortnights
|
40
|
+
self * 2.weeks
|
41
|
+
end
|
42
|
+
alias :fortnight :fortnights
|
43
|
+
|
44
|
+
def months
|
45
|
+
self * 30.days
|
46
|
+
end
|
47
|
+
alias :month :months
|
48
|
+
|
49
|
+
def years
|
50
|
+
(self * 365.25.days).to_i
|
51
|
+
end
|
52
|
+
alias :year :years
|
53
|
+
|
54
|
+
# Reads best without arguments: 10.minutes.ago
|
55
|
+
def ago(time = ::Time.now)
|
56
|
+
time - self
|
57
|
+
end
|
58
|
+
|
59
|
+
# Reads best with argument: 10.minutes.until(time)
|
60
|
+
alias :until :ago
|
61
|
+
|
62
|
+
# Reads best with argument: 10.minutes.since(time)
|
63
|
+
def since(time = ::Time.now)
|
64
|
+
time + self
|
65
|
+
end
|
66
|
+
|
67
|
+
# Reads best without arguments: 10.minutes.from_now
|
68
|
+
alias :from_now :since
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module ShatteredSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module String #:nodoc:
|
4
|
+
# Makes it easier to access parts of a string, such as specific characters and substrings.
|
5
|
+
module Access
|
6
|
+
# Returns the character at the +position+ treating the string as an array (where 0 is the first character).
|
7
|
+
#
|
8
|
+
# Examples:
|
9
|
+
# "hello".at(0) # => "h"
|
10
|
+
# "hello".at(4) # => "o"
|
11
|
+
# "hello".at(10) # => nil
|
12
|
+
def at(position)
|
13
|
+
self[position, 1]
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the remaining of the string from the +position+ treating the string as an array (where 0 is the first character).
|
17
|
+
#
|
18
|
+
# Examples:
|
19
|
+
# "hello".from(0) # => "hello"
|
20
|
+
# "hello".from(2) # => "llo"
|
21
|
+
# "hello".from(10) # => nil
|
22
|
+
def from(position)
|
23
|
+
self[position..-1]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the beginning of the string up to the +position+ treating the string as an array (where 0 is the first character).
|
27
|
+
#
|
28
|
+
# Examples:
|
29
|
+
# "hello".to(0) # => "h"
|
30
|
+
# "hello".to(2) # => "hel"
|
31
|
+
# "hello".to(10) # => "hello"
|
32
|
+
def to(position)
|
33
|
+
self[0..position]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the first character of the string or the first +limit+ characters.
|
37
|
+
#
|
38
|
+
# Examples:
|
39
|
+
# "hello".first # => "h"
|
40
|
+
# "hello".first(2) # => "he"
|
41
|
+
# "hello".first(10) # => "hello"
|
42
|
+
def first(limit = 1)
|
43
|
+
self[0..(limit - 1)]
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the last character of the string or the last +limit+ characters.
|
47
|
+
#
|
48
|
+
# Examples:
|
49
|
+
# "hello".last # => "o"
|
50
|
+
# "hello".last(2) # => "lo"
|
51
|
+
# "hello".last(10) # => "hello"
|
52
|
+
def last(limit = 1)
|
53
|
+
self[(-limit)..-1] || self
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'parsedate'
|
2
|
+
|
3
|
+
module ShatteredSupport #:nodoc:
|
4
|
+
module CoreExtensions #:nodoc:
|
5
|
+
module String #:nodoc:
|
6
|
+
# Converting strings to other objects
|
7
|
+
module Conversions
|
8
|
+
# Form can be either :utc (default) or :local.
|
9
|
+
def to_time(form = :utc)
|
10
|
+
::Time.send(form, *ParseDate.parsedate(self))
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_date
|
14
|
+
::Date.new(*ParseDate.parsedate(self)[0..2])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../inflector' unless defined? Inflector
|
2
|
+
module ShatteredSupport #:nodoc:
|
3
|
+
module CoreExtensions #:nodoc:
|
4
|
+
module String #:nodoc:
|
5
|
+
# Makes it possible to do "posts".singularize that returns "post" and "MegaCoolClass".underscore that returns "mega_cool_class".
|
6
|
+
module Inflections
|
7
|
+
def pluralize
|
8
|
+
Inflector.pluralize(self)
|
9
|
+
end
|
10
|
+
|
11
|
+
def singularize
|
12
|
+
Inflector.singularize(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def camelize(first_letter = :upper)
|
16
|
+
case first_letter
|
17
|
+
when :upper then Inflector.camelize(self, true)
|
18
|
+
when :lower then Inflector.camelize(self, false)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
alias_method :camelcase, :camelize
|
22
|
+
|
23
|
+
def titleize
|
24
|
+
Inflector.titleize(self)
|
25
|
+
end
|
26
|
+
alias_method :titlecase, :titleize
|
27
|
+
|
28
|
+
def underscore
|
29
|
+
Inflector.underscore(self)
|
30
|
+
end
|
31
|
+
|
32
|
+
def dasherize
|
33
|
+
Inflector.dasherize(self)
|
34
|
+
end
|
35
|
+
|
36
|
+
def demodulize
|
37
|
+
Inflector.demodulize(self)
|
38
|
+
end
|
39
|
+
|
40
|
+
def tableize
|
41
|
+
Inflector.tableize(self)
|
42
|
+
end
|
43
|
+
|
44
|
+
def classify
|
45
|
+
Inflector.classify(self)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Capitalizes the first word and turns underscores into spaces and strips _id, so "employee_salary" becomes "Employee salary"
|
49
|
+
# and "author_id" becomes "Author".
|
50
|
+
def humanize
|
51
|
+
Inflector.humanize(self)
|
52
|
+
end
|
53
|
+
|
54
|
+
def foreign_key(separate_class_name_and_id_with_underscore = true)
|
55
|
+
Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
|
56
|
+
end
|
57
|
+
|
58
|
+
def constantize
|
59
|
+
Inflector.constantize(self)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
3
|
+
module ShatteredSupport #:nodoc:
|
4
|
+
module CoreExtensions #:nodoc:
|
5
|
+
module String #:nodoc:
|
6
|
+
# Custom string iterators
|
7
|
+
module Iterators
|
8
|
+
# Yields a single-character string for each character in the string.
|
9
|
+
# When $KCODE = 'UTF8', multi-byte characters are yielded appropriately.
|
10
|
+
def each_char
|
11
|
+
scanner, char = StringScanner.new(self), /./mu
|
12
|
+
loop { yield(scanner.scan(char) || break) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ShatteredSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module String #:nodoc:
|
4
|
+
# Additional string tests.
|
5
|
+
module StartsEndsWith
|
6
|
+
# Does the string start with the specified +prefix+?
|
7
|
+
def starts_with?(prefix)
|
8
|
+
prefix = prefix.to_s
|
9
|
+
self[0, prefix.length] == prefix
|
10
|
+
end
|
11
|
+
|
12
|
+
# Does the string end with the specified +suffix+?
|
13
|
+
def ends_with?(suffix)
|
14
|
+
suffix = suffix.to_s
|
15
|
+
self[-suffix.length, suffix.length] == suffix
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/string/inflections'
|
2
|
+
require File.dirname(__FILE__) + '/string/conversions'
|
3
|
+
require File.dirname(__FILE__) + '/string/access'
|
4
|
+
require File.dirname(__FILE__) + '/string/starts_ends_with'
|
5
|
+
require File.dirname(__FILE__) + '/string/iterators'
|
6
|
+
|
7
|
+
class String #:nodoc:
|
8
|
+
include ShatteredSupport::CoreExtensions::String::Access
|
9
|
+
include ShatteredSupport::CoreExtensions::String::Conversions
|
10
|
+
include ShatteredSupport::CoreExtensions::String::Inflections
|
11
|
+
include ShatteredSupport::CoreExtensions::String::StartsEndsWith
|
12
|
+
include ShatteredSupport::CoreExtensions::String::Iterators
|
13
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].each { |file| require(file) }
|
@@ -0,0 +1,53 @@
|
|
1
|
+
Inflector.inflections do |inflect|
|
2
|
+
inflect.plural(/$/, 's')
|
3
|
+
inflect.plural(/s$/i, 's')
|
4
|
+
inflect.plural(/(ax|test)is$/i, '\1es')
|
5
|
+
inflect.plural(/(octop|vir)us$/i, '\1i')
|
6
|
+
inflect.plural(/(alias|status)$/i, '\1es')
|
7
|
+
inflect.plural(/(bu)s$/i, '\1ses')
|
8
|
+
inflect.plural(/(buffal|tomat)o$/i, '\1oes')
|
9
|
+
inflect.plural(/([ti])um$/i, '\1a')
|
10
|
+
inflect.plural(/sis$/i, 'ses')
|
11
|
+
inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
|
12
|
+
inflect.plural(/(hive)$/i, '\1s')
|
13
|
+
inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
|
14
|
+
inflect.plural(/([^aeiouy]|qu)ies$/i, '\1y')
|
15
|
+
inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
|
16
|
+
inflect.plural(/(matr|vert|ind)ix|ex$/i, '\1ices')
|
17
|
+
inflect.plural(/([m|l])ouse$/i, '\1ice')
|
18
|
+
inflect.plural(/^(ox)$/i, '\1en')
|
19
|
+
inflect.plural(/(quiz)$/i, '\1zes')
|
20
|
+
|
21
|
+
inflect.singular(/s$/i, '')
|
22
|
+
inflect.singular(/(n)ews$/i, '\1ews')
|
23
|
+
inflect.singular(/([ti])a$/i, '\1um')
|
24
|
+
inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis')
|
25
|
+
inflect.singular(/(^analy)ses$/i, '\1sis')
|
26
|
+
inflect.singular(/([^f])ves$/i, '\1fe')
|
27
|
+
inflect.singular(/(hive)s$/i, '\1')
|
28
|
+
inflect.singular(/(tive)s$/i, '\1')
|
29
|
+
inflect.singular(/([lr])ves$/i, '\1f')
|
30
|
+
inflect.singular(/([^aeiouy]|qu)ies$/i, '\1y')
|
31
|
+
inflect.singular(/(s)eries$/i, '\1eries')
|
32
|
+
inflect.singular(/(m)ovies$/i, '\1ovie')
|
33
|
+
inflect.singular(/(x|ch|ss|sh)es$/i, '\1')
|
34
|
+
inflect.singular(/([m|l])ice$/i, '\1ouse')
|
35
|
+
inflect.singular(/(bus)es$/i, '\1')
|
36
|
+
inflect.singular(/(o)es$/i, '\1')
|
37
|
+
inflect.singular(/(shoe)s$/i, '\1')
|
38
|
+
inflect.singular(/(cris|ax|test)es$/i, '\1is')
|
39
|
+
inflect.singular(/([octop|vir])i$/i, '\1us')
|
40
|
+
inflect.singular(/(alias|status)es$/i, '\1')
|
41
|
+
inflect.singular(/^(ox)en/i, '\1')
|
42
|
+
inflect.singular(/(vert|ind)ices$/i, '\1ex')
|
43
|
+
inflect.singular(/(matr)ices$/i, '\1ix')
|
44
|
+
inflect.singular(/(quiz)zes$/i, '\1')
|
45
|
+
|
46
|
+
inflect.irregular('person', 'people')
|
47
|
+
inflect.irregular('man', 'men')
|
48
|
+
inflect.irregular('child', 'children')
|
49
|
+
inflect.irregular('sex', 'sexes')
|
50
|
+
inflect.irregular('move', 'moves')
|
51
|
+
|
52
|
+
inflect.uncountable(%w(equipment information rice money species series fish sheep))
|
53
|
+
end
|