mack-facets 0.6.0

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/README ADDED
@@ -0,0 +1,3 @@
1
+ README
2
+ ========================================================================
3
+ mack-facets was developed by: markbates
@@ -0,0 +1,50 @@
1
+ module English # :nodoc:
2
+
3
+ # = English Nouns Number Inflection.
4
+ #
5
+ # This module provides english singular <-> plural noun inflections.
6
+ module Inflect # :nodoc:
7
+
8
+ class << self
9
+
10
+ # Convert an English word from plurel to singular.
11
+ #
12
+ # "boys".singular #=> boy
13
+ # "tomatoes".singular #=> tomato
14
+ #
15
+ def singular(word)
16
+ if result = singular_of[word]
17
+ return result.dup
18
+ end
19
+ result = word.dup
20
+ singularization_rules.each do |(match, replacement)|
21
+ break if result.gsub!(match, replacement)
22
+ end
23
+ # Mack: cache the result of the translation:
24
+ singular_of[word] = result unless word == result
25
+ return result
26
+ end
27
+
28
+ # Convert an English word from singular to plurel.
29
+ #
30
+ # "boy".plural #=> boys
31
+ # "tomato".plural #=> tomatoes
32
+ #
33
+ def plural(word)
34
+ if result = plural_of[word]
35
+ return result.dup
36
+ end
37
+ #return self.dup if /s$/ =~ self # ???
38
+ result = word.dup
39
+ pluralization_rules.each do |(match, replacement)|
40
+ break if result.gsub!(match, replacement)
41
+ end
42
+ # Mack: cache the result of the translation:
43
+ plural_of[word] = result unless word == result
44
+ return result
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,12 @@
1
+ class Integer #:nodoc:
2
+
3
+ #
4
+ # 10.english #=> 'ten'
5
+
6
+ include English::Numerals
7
+
8
+ def english
9
+ self.name(self)
10
+ end
11
+
12
+ end
@@ -0,0 +1,90 @@
1
+ class Array
2
+
3
+ # This method is useful when you have a method that looks like this:
4
+ # def foo(*args)
5
+ # do something
6
+ # end
7
+ # The problem is when you use the * like that everything that comes in is
8
+ # an array. Here are a few problems with this:
9
+ # foo([1,2,3])
10
+ # When you pass an array into this type of method you get the following nested array:
11
+ # [[1,2,3]]
12
+ # The parse_splat_args method, if called, would do this:
13
+ # args.parse_splat_args # => [1,2,3]
14
+ # Now say you called this method like such:
15
+ # foo(1)
16
+ # args would be [1]
17
+ # args.parse_splat_args # => 1
18
+ # Finally
19
+ # foo
20
+ # args.parse_splat_args # => nil
21
+ def parse_splat_args
22
+ unless self.empty?
23
+ args = self#.flatten
24
+ case args.size
25
+ when 1
26
+ return args.first # if there was only one arg passed, return just that, without the array
27
+ when 0
28
+ return nil # if no args were passed return nil
29
+ else
30
+ return args # else return the array back, cause chances are that's what they passed you!
31
+ end
32
+ end
33
+ end
34
+
35
+ # This will return a new instance of the array sorted randomly.
36
+ def randomize(&block)
37
+ if block_given?
38
+ self.sort {|x,y| yield x, y}
39
+ else
40
+ self.sort_by { rand }
41
+ end
42
+ end
43
+
44
+ # This calls the randomize method, but will permantly replace the existing array.
45
+ def randomize!(&block)
46
+ if block_given?
47
+ self.replace(self.randomize(&block))
48
+ else
49
+ self.replace(self.randomize)
50
+ end
51
+ end
52
+
53
+ # This will pick a random value from the array
54
+ def pick_random
55
+ self[rand(self.length)]
56
+ end
57
+
58
+ # This allows you to easily recurse of the array randomly.
59
+ def random_each
60
+ self.randomize.each {|x| yield x}
61
+ end
62
+
63
+ def subset?(other)
64
+ self.each do |x|
65
+ return false if !(other.include? x)
66
+ end
67
+ true
68
+ end
69
+
70
+ def superset?(other)
71
+ other.subset?(self)
72
+ end
73
+
74
+ # This will give you a count, as a Hash, of all the values in the Array.
75
+ # %w{spam spam eggs ham eggs spam}.count # => {"eggs" => 2, "ham" => 1, "spam" => 3}
76
+ def count
77
+ k = Hash.new(0)
78
+ self.each{|x| k[x] += 1}
79
+ k
80
+ end
81
+
82
+ # This will invert the index and the values and return a Hash of the results.
83
+ # %w{red yellow orange}.invert # => {"red" => 0, "orange" => 2, "yellow" => 1}
84
+ def invert
85
+ h = {}
86
+ self.each_with_index{|x,i| h[x] = i}
87
+ h
88
+ end
89
+
90
+ end
@@ -0,0 +1,38 @@
1
+ class Class
2
+
3
+ # Returns a new Object instance of the class name specified.
4
+ #
5
+ # Examples:
6
+ # Class.new_instance_of("Orange") => #<Orange:0x376c0c>
7
+ # Class.new_instance_of("Animals::Dog") => #<Animals::Dog:0x376a2c>
8
+ def self.new_instance_of(klass_name)
9
+ klass_name.constantize.new
10
+ end
11
+
12
+ # This will through the ancestor tree of object and tell you if
13
+ # that object is of the specified type.
14
+ def class_is_a?(klass_name)
15
+ self.ancestors.each do |an|
16
+ if an == klass_name
17
+ return true
18
+ end
19
+ end
20
+ return false
21
+ end
22
+
23
+ # Returns an array of the classes parent classes.
24
+ #
25
+ # Examples:
26
+ # Orange.parents # => [Citrus, Fruit, Object]
27
+ # Citrus.parents # => [Fruit, Object]
28
+ # Fruit.parents # => [Object]
29
+ def parents
30
+ ans = [self.superclass]
31
+ until ans.last.superclass.nil?
32
+ ans << ans.last.superclass
33
+ end
34
+ ans
35
+ end
36
+
37
+ end
38
+
@@ -0,0 +1,49 @@
1
+ require 'uri'
2
+ class Hash
3
+
4
+ def join(pair_string, join_string)
5
+ output = []
6
+ sorted = self.sort {|a,b| a[0].to_s <=> b[0].to_s}
7
+ sorted.each do |ar|
8
+ output << sprintf(pair_string, ar[0], ar[1])
9
+ end
10
+ output.join(join_string)
11
+ end
12
+
13
+ # Deletes the key(s) passed in from the hash.
14
+ def -(ars)
15
+ [ars].flatten.each {|a| self.delete(a)}
16
+ self
17
+ end
18
+
19
+ # Converts a hash to query string parameters.
20
+ # An optional boolean escapes the values if true, which is the default.
21
+ def to_params(escape = true)
22
+ params = ''
23
+ stack = []
24
+
25
+ each do |k, v|
26
+ if v.is_a?(Hash)
27
+ stack << [k,v]
28
+ else
29
+ v = v.to_s.uri_escape if escape
30
+ params << "#{k}=#{v}&"
31
+ end
32
+ end
33
+
34
+ stack.each do |parent, hash|
35
+ hash.each do |k, v|
36
+ if v.is_a?(Hash)
37
+ stack << ["#{parent}[#{k}]", v]
38
+ else
39
+ v = v.to_s.uri_escape if escape
40
+ params << "#{parent}[#{k}]=#{v}&"
41
+ end
42
+ end
43
+ end
44
+
45
+ params.chop! # trailing &
46
+ params.split("&").sort.join("&")
47
+ end
48
+
49
+ end
@@ -0,0 +1,34 @@
1
+ require 'pp'
2
+ require 'stringio'
3
+
4
+ module Kernel
5
+
6
+ def pp_to_s(object)
7
+ pp_out = StringIO.new
8
+ PP.pp(object,pp_out)
9
+ return pp_out.string
10
+ end
11
+
12
+ def retryable(options = {}, &block)
13
+ opts = { :tries => 1, :on => Exception }.merge(options)
14
+
15
+ retries = opts[:tries]
16
+ retry_exceptions = [opts[:on]].flatten
17
+
18
+ x = %{
19
+ begin
20
+ return yield
21
+ rescue #{retry_exceptions.join(", ")} => e
22
+ retries -= 1
23
+ if retries > 0
24
+ retry
25
+ else
26
+ raise e
27
+ end
28
+ end
29
+ }
30
+
31
+ eval(x, &block)
32
+ end
33
+
34
+ end
@@ -0,0 +1,15 @@
1
+ module Math
2
+
3
+ def self.log2(x)
4
+ self.log(x)/self.log(2.0)
5
+ end
6
+
7
+ def self.min(a, b)
8
+ a < b ? a : b
9
+ end
10
+
11
+ def self.max(a, b)
12
+ a > b ? a : b
13
+ end
14
+
15
+ end
@@ -0,0 +1,29 @@
1
+ class Module
2
+
3
+ # Bulk converts the security level of methods in this Module from one level to another.
4
+ def convert_security_of_methods(old_level = :public, new_level = :protected)
5
+ eval("#{old_level}_instance_methods").each{ |meth| self.send(new_level, meth) }
6
+ self
7
+ end
8
+
9
+ # Includes this module into a Class, and changes all public methods to protected.
10
+ #
11
+ # Examples:
12
+ # module MyCoolUtils
13
+ # def some_meth
14
+ # "hi"
15
+ # end
16
+ # self.include_safely_into(FooController)
17
+ # end
18
+ # or:
19
+ # MyCoolUtils.include_safely_into(FooController, SomeOtherClass)
20
+ def include_safely_into(*args)
21
+ [args].flatten.each do |a|
22
+ if a.is_a?(String) || a.is_a?(Symbol)
23
+ a = a.to_s.constantize
24
+ end
25
+ a.send(:include, self.convert_security_of_methods)
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,164 @@
1
+ class Object
2
+
3
+ # Includes a module into the current Class, and changes all the module's public methods to protected.
4
+ #
5
+ # Example:
6
+ # class FooController
7
+ # safely_include_module(MyCoolUtils, MyOtherModule)
8
+ # end
9
+ def safely_include_module(*modules)
10
+ [modules].flatten.each do |mod|
11
+ mod.include_safely_into(self)
12
+ end
13
+ end
14
+
15
+ # Prints out the methods associated with this object in alphabetical order.
16
+ def print_methods
17
+ m = "----- #{self} (methods) -----\n"
18
+ m << methods.sort.join("\n")
19
+ puts m
20
+ m
21
+ end
22
+
23
+ # An elegant way to refactor out common options
24
+ #
25
+ # with_options :order => 'created_at', :class_name => 'Comment' do |post|
26
+ # post.has_many :comments, :conditions => ['approved = ?', true], :dependent => :delete_all
27
+ # post.has_many :unapproved_comments, :conditions => ['approved = ?', false]
28
+ # post.has_many :all_comments
29
+ # end
30
+ #
31
+ # Can also be used with an explicit receiver:
32
+ #
33
+ # map.with_options :controller => "people" do |people|
34
+ # people.connect "/people", :action => "index"
35
+ # people.connect "/people/:id", :action => "show"
36
+ # end
37
+ #
38
+ def with_options(options)
39
+ yield Mack::Utils::OptionMerger.new(self, options)
40
+ end
41
+
42
+ # See Class parents for more information.
43
+ def class_parents
44
+ self.class.parents
45
+ end
46
+
47
+ # This method gets called when a parameter is passed into a named route.
48
+ # This can be overridden in an Object to provlde custom handling of parameters.
49
+ def to_param
50
+ self.to_s
51
+ end
52
+
53
+ # Uses <code>define_method</code> to create an empty for the method parameter defined.
54
+ # That method will then raise MethodNotImplemented. This is useful for creating interfaces
55
+ # and you want to stub out methods that others need to implement.
56
+ def self.needs_method(meth)
57
+ define_method(meth) do
58
+ raise NoMethodError.new("The interface you are using requires you define the following method '#{meth}'")
59
+ end
60
+ end
61
+
62
+ # This prints out running time for the block provided. This is great for things
63
+ # like Rake tasks, etc... where you would like to know how long it, or a section of
64
+ # it took to run.
65
+ def running_time(message = "", logger = nil)
66
+ s_time = Time.now
67
+ s = "---Starting at #{s_time}---"
68
+ puts s
69
+ logger.info s unless logger.nil?
70
+ yield if block_given?
71
+ e_time = Time.now
72
+ e = "---Ending at #{e_time}---"
73
+ puts e
74
+ logger.info e unless logger.nil?
75
+ secs = e_time - s_time
76
+ if secs < 60
77
+ x = "Running time #{secs} seconds."
78
+ else
79
+ x = "Running time roughly #{secs/60} minutes [#{secs} seconds]"
80
+ end
81
+ x += " [MESSAGE]: #{message}" unless message.blank?
82
+ puts x
83
+ logger.info x unless logger.nil?
84
+ end
85
+
86
+ # This method will call send to all the methods defined on the previous method.
87
+ #
88
+ # Example:
89
+ # Fruit.send_with_chain([:new, :get_citrus, :get_orange, :class]) # => Orange
90
+ #
91
+ # This would be the equivalent:
92
+ # Fruit.new.get_citrus.get_orange.class
93
+ def send_with_chain(methods, *args)
94
+ obj = self
95
+ [methods].flatten.each {|m| obj = obj.send(m, *args)}
96
+ obj
97
+ end
98
+
99
+ # ivar_cache allows you to cache the results of the block into an instance variable in a class,
100
+ # and then will serve up that instance variable the next time you call that method again.
101
+ #
102
+ # old way:
103
+ # def show_page_link
104
+ # unless @show_page_link # check if instance variable exists
105
+ # # if the instance variable doesn't exist let's do some work and assign it to the instance variable.
106
+ # @show_page_link = link_to("show", some_url(:id => self.id, :foo => bar, etc... => etc))
107
+ # end
108
+ # @show_page_link # now return the instance variable
109
+ # end
110
+ #
111
+ # new way:
112
+ # def show_page_link
113
+ # ivar_cache do
114
+ # link_to("show", some_url(:id => self.id, :foo => bar, etc... => etc))
115
+ # end
116
+ # end
117
+ #
118
+ # this does everything the old way did, but it is much cleaner, and a lot less code!
119
+ # in case you're wondering it caches the result, by default, to an instance variable named after the method,
120
+ # so in our above example the instance variable would be name, <code>@show_page_link</code>. this can be overridden like such:
121
+ #
122
+ # def show_page_link
123
+ # ivar_cache("foo_var") do
124
+ # link_to("show", some_url(:id => self.id, :foo => bar, etc... => etc))
125
+ # end
126
+ # end
127
+ #
128
+ # now it will cache it to <code>@foo_var</code>
129
+ def ivar_cache(var_name = nil, &block)
130
+ if var_name.nil?
131
+ call = caller[0]
132
+ var_name = call[(call.index('`')+1)...call.index("'")]
133
+ end
134
+ var = instance_variable_get("@#{var_name}")
135
+ unless var
136
+ return instance_variable_set("@#{var_name}", yield) if block_given?
137
+ end
138
+ instance_variable_get("@#{var_name}")
139
+ end
140
+
141
+ def ivar_cache_clear(var_name = nil, &block)
142
+ if var_name.nil?
143
+ call = caller[0]
144
+ var_name = call[(call.index('`')+1)...call.index("'")]
145
+ end
146
+ remove_instance_variable("@#{var_name}") #rescue
147
+ yield if block_given?
148
+ end
149
+
150
+ # Returns the namespaces for a particular object.
151
+ #
152
+ # Examples:
153
+ # Animals::Dog::Poodle.new.namespaces # => ["Animals", "Dog"]
154
+ def namespaces
155
+ ivar_cache("object_namespaces") do
156
+ nss = []
157
+ full_name = self.class.name.to_s
158
+ nss = full_name.split("::")
159
+ nss.pop
160
+ nss
161
+ end
162
+ end
163
+
164
+ end
@@ -0,0 +1,218 @@
1
+ class String
2
+ include Style
3
+
4
+ def methodize
5
+ x = self
6
+
7
+ # if we get down to a nil or an empty string raise an exception!
8
+ raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
9
+
10
+ # get rid of the big stuff in the front/back
11
+ x.strip!
12
+
13
+ # if we get down to a nil or an empty string raise an exception!
14
+ raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
15
+
16
+ x = x.underscore
17
+
18
+ # get rid of spaces and make the _
19
+ x.gsub!(' ', '_')
20
+ # get rid of everything that isn't 'safe' a-z, 0-9, ?, !, =, _
21
+ x.gsub!(/([^ a-zA-Z0-9\_\?\!\=]+)/n, '_')
22
+
23
+ # if we get down to a nil or an empty string raise an exception!
24
+ raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
25
+
26
+ # condense multiple 'safe' non a-z chars to just one.
27
+ # ie. ___ becomes _ !!!! becomes ! etc...
28
+ [' ', '_', '?', '!', "="].each do |c|
29
+ x.squeeze!(c)
30
+ end
31
+
32
+ # if we get down to a nil or an empty string raise an exception!
33
+ raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
34
+
35
+ #down case the whole thing
36
+ x.downcase!
37
+
38
+ # get rid of any characters at the beginning that aren't a-z
39
+ while !x.match(/^[a-z]/)
40
+ x.slice!(0)
41
+
42
+ # if we get down to a nil or an empty string raise an exception!
43
+ raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
44
+ end
45
+
46
+ # let's trim this bad boy down a bit now that we've cleaned it up, somewhat.
47
+ # we should do this before cleaning up the end character, because it's possible to end up with a
48
+ # bad char at the end if you trim too late.
49
+ x = x[0..100] if x.length > 100
50
+
51
+ # get rid of any characters at the end that aren't safe
52
+ while !x.match(/[a-z0-9\?\!\=]$/)
53
+ x.slice!(x.length - 1)
54
+ # if we get down to a nil or an empty string raise an exception!
55
+ raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
56
+ end
57
+
58
+ # if we get down to a nil or an empty string raise an exception!
59
+ raise NameError.new("#{self} cannot be converted to a valid method name!") if x.nil? || x == ''
60
+
61
+ # let's get rid of characters that don't belong in the 'middle' of the method.
62
+ orig_middle = x[1..(x.length - 2)]
63
+ n_middle = orig_middle.dup
64
+
65
+ ['?', '!', "="].each do |c|
66
+ n_middle.gsub!(c, "_")
67
+ end
68
+
69
+ # the previous gsub can leave us with multiple underscores that need cleaning up.
70
+ n_middle.squeeze!("_")
71
+
72
+ x.gsub!(orig_middle, n_middle)
73
+ x.gsub!("_=", "=")
74
+ x
75
+ end
76
+
77
+ # Returns a constant of the string.
78
+ #
79
+ # Examples:
80
+ # "User".constantize # => User
81
+ # "HomeController".constantize # => HomeController
82
+ # "Mack::Configuration" # => Mack::Configuration
83
+ def constantize
84
+ Module.instance_eval("::#{self}")
85
+ end
86
+
87
+ def hexdigest
88
+ Digest::SHA1.hexdigest(self)
89
+ end
90
+
91
+ def hexdigest!
92
+ self.replace(self.hexdigest)
93
+ end
94
+
95
+ def self.randomize(length = 10)
96
+ chars = ("A".."H").to_a + ("J".."N").to_a + ("P".."T").to_a + ("W".."Z").to_a + ("3".."9").to_a
97
+ newpass = ""
98
+ 1.upto(length) { |i| newpass << chars[rand(chars.size-1)] }
99
+ return newpass.upcase
100
+ end
101
+
102
+ # Performs URI escaping so that you can construct proper
103
+ # query strings faster. Use this rather than the cgi.rb
104
+ # version since it's faster. (Stolen from Camping).
105
+ def uri_escape
106
+ self.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
107
+ '%'+$1.unpack('H2'*$1.size).join('%').upcase
108
+ }.tr(' ', '+')
109
+ end
110
+
111
+ # Unescapes a URI escaped string. (Stolen from Camping).
112
+ def uri_unescape
113
+ self.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){
114
+ [$1.delete('%')].pack('H*')
115
+ }
116
+ end
117
+
118
+ def truncate(length = 30, truncate_string = "...")
119
+ if self.nil? then return end
120
+ l = length - truncate_string.length
121
+ if $KCODE == "NONE"
122
+ self.length > length ? self[0...l] + truncate_string : self
123
+ else
124
+ chars = self.split(//)
125
+ chars.length > length ? chars[0...l].join + truncate_string : self
126
+ end
127
+ end
128
+
129
+ def truncate!(length = 30, truncate_string = "...")
130
+ self.replace(self.truncate(length, truncate_string))
131
+ end
132
+
133
+ end
134
+ # require 'digest'
135
+ # class String
136
+ #
137
+ # # Maps to Mack::Utils::Inflector.instance.pluralize
138
+ # def plural
139
+ # Mack::Utils::Inflector.instance.pluralize(self)
140
+ # end
141
+ #
142
+ # # Maps to Mack::Utils::Inflector.instance.singularize
143
+ # def singular
144
+ # Mack::Utils::Inflector.instance.singularize(self)
145
+ # end
146
+ #
147
+
148
+ #
149
+ #
150
+ # def underscore
151
+ # camel_cased_word = self.dup
152
+ # camel_cased_word.to_s.gsub(/::/, '/').
153
+ # gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
154
+ # gsub(/([a-z\d])([A-Z])/,'\1_\2').
155
+ # tr("-", "_").
156
+ # downcase
157
+ # end
158
+ #
159
+ # def starts_with?(x)
160
+ # self.match(/^#{x}/) ? true : false
161
+ # end
162
+ #
163
+ # def ends_with?(x)
164
+ # self.match(/#{x}$/) ? true : false
165
+ # end
166
+ #
167
+ # # Returns "is" or "are" based on the number, i.e. "i=6; There #{isare(i)} #{i} topics here."
168
+ # def self.pluralize_word(num, vals = ["is", "are"])
169
+ # return vals[0] if num.to_i==1
170
+ # return vals[1]
171
+ # end
172
+ #
173
+ # def remove(val)
174
+ # gsub(val, '')
175
+ # end
176
+ #
177
+ # def remove!(val)
178
+ # gsub!(val, '')
179
+ # end
180
+ #
181
+
182
+ #
183
+ # def truncate(length = 30, truncate_string = "...")
184
+ # if self.nil? then return end
185
+ # l = length - truncate_string.length
186
+ # if $KCODE == "NONE"
187
+ # self.length > length ? self[0...l] + truncate_string : self
188
+ # else
189
+ # chars = self.split(//)
190
+ # chars.length > length ? chars[0...l].join + truncate_string : self
191
+ # end
192
+ # end
193
+ #
194
+ # def truncate!(length = 30, truncate_string = "...")
195
+ # self.replace(self.truncate(length, truncate_string))
196
+ # end
197
+ #
198
+ # def capitalize_all_words
199
+ # self.gsub(/\b\w/) {|s| s.upcase}
200
+ # end
201
+ #
202
+ # def capitalize_all_words!
203
+ # self.replace(self.capitalize_all_words)
204
+ # end
205
+ #
206
+ # # keep adding on to this whenever it becomes apparent that unsafe strings
207
+ # # could get passed through into the database
208
+ # def sql_safe_str
209
+ # if !self.nil?
210
+ # self.gsub(/[\']/, "\'\'")
211
+ # end
212
+ # end
213
+ #
214
+ # def sql_safe_str!
215
+ # self.replace(self.sql_safe_str)
216
+ # end
217
+ #
218
+ # end
@@ -0,0 +1,7 @@
1
+ class Symbol
2
+
3
+ def methodize
4
+ self.to_s.methodize
5
+ end
6
+
7
+ end
@@ -0,0 +1,31 @@
1
+ require 'rubygems'
2
+ require 'digest'
3
+ require 'facets'
4
+ require 'facets/ruby'
5
+ require 'facets/style'
6
+ require 'facets/blank'
7
+ require 'facets/hash'
8
+ require 'facets/hash/symbolize_keys'
9
+ require 'facets/hash/stringify_keys'
10
+ require 'facets/module'
11
+ require 'facets/infinity'
12
+ require 'english/inflect'
13
+ require 'english/numerals'
14
+ [:inflector, :inflections, :options_merger].each do |k|
15
+ path = File.join File.dirname(__FILE__), "utils", "#{k}"
16
+ #puts "requiring #{path}"
17
+ require path
18
+ end
19
+
20
+ [:array, :class, :hash, :kernel, :math, :module, :object, :string, :symbol].each do |k|
21
+ path = File.join File.dirname(__FILE__), "extensions", "#{k}"
22
+ #puts "requiring #{path}"
23
+ require path
24
+ end
25
+
26
+ [:numerals, :inflect].each do |k|
27
+ path = File.join File.dirname(__FILE__), "english_extensions", "#{k}"
28
+ #puts "requiring #{path}"
29
+ require path
30
+ end
31
+
@@ -0,0 +1,63 @@
1
+ require File.join(File.dirname(__FILE__), "inflector")
2
+ # Default inflections. This is taken from Jeremy McAnally's great Rails plugin, acts_as_good_speeler. Thanks Jeremy! http://www.jeremymcanally.com/
3
+ Mack::Utils::Inflector.inflections do |inflect|
4
+ # inflect.plural(/$/, 's')
5
+ inflect.plural(/s$/i, 's')
6
+ inflect.plural(/(bu)s$/i, '\1ses')
7
+ inflect.plural(/(stimul|hippopotam|octop|vir|syllab|foc|alumn|fung|radi)us$/i, '\1i')
8
+ inflect.plural(/(ax|test)is$/i, '\1es')
9
+ inflect.plural(/(alias|status)$/i, '\1es')
10
+ inflect.plural(/(buffal|tomat|torped)o$/i, '\1oes')
11
+ inflect.plural(/([dti])um$/i, '\1a')
12
+ inflect.plural(/sis$/i, 'ses')
13
+ inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
14
+ inflect.plural(/(hive)$/i, '\1s')
15
+ inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
16
+ inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
17
+ inflect.plural(/(matr|append|vert|ind)ix|ex$/i, '\1ices')
18
+ inflect.plural(/([m|l])ouse$/i, '\1ice')
19
+ inflect.plural(/^(ox)$/i, '\1en')
20
+ inflect.plural(/(quiz)$/i, '\1zes')
21
+ inflect.plural(/(phenomen|criteri)on$/i, '\1a')
22
+ inflect.plural(/^(?!(.*hu|.*ger|.*sha))(.*)(wom|m)an$/i, '\2\3en')
23
+ inflect.plural(/(curricul|bacteri|medi)um$/i, '\1a')
24
+ inflect.plural(/(nebul|formul|vit|vertebr|alg|alumn)a$/i, '\1ae')
25
+
26
+ # inflect.singular(/s$/i, '')
27
+ inflect.singular(/(n)ews$/i, '\1ews')
28
+ inflect.singular(/([dti])a$/i, '\1um')
29
+ inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis')
30
+ inflect.singular(/(^analy|cri|empha)ses$/i, '\1sis')
31
+ inflect.singular(/([^f])ves$/i, '\1fe')
32
+ inflect.singular(/(hive)s$/i, '\1')
33
+ inflect.singular(/(tive)s$/i, '\1')
34
+ inflect.singular(/(bus)es$/i, '\1')
35
+ inflect.singular(/(o)es$/i, '\1')
36
+ inflect.singular(/(shoe)s$/i, '\1')
37
+ inflect.singular(/(test|ax)es$/i, '\1is')
38
+ inflect.singular(/(stimul|hippopotam|octop|vir|syllab|foc|alumn|fung|radi)i$/i, '\1us')
39
+ inflect.singular(/(alias|status)es$/i, '\1')
40
+ inflect.singular(/^(ox)en$/i, '\1')
41
+ inflect.singular(/(vert|ind)ices$/i, '\1ex')
42
+ inflect.singular(/(matr|append)ices$/i, '\1ix')
43
+ inflect.singular(/(quiz)zes$/i, '\1')
44
+ inflect.singular(/(phenomen|criteri)a$/i, '\1on')
45
+ inflect.singular(/(.*)(wo|m)en$/i, '\1\2an')
46
+ inflect.singular(/(medi|curricul|bacteri)a$/i, '\1um')
47
+ inflect.singular(/(nebula|formula|vita|vertebra|alga|alumna)e$/i, '\1')
48
+ inflect.singular(/^(.*)ookies$/, '\1ookie')
49
+ inflect.singular(/(.*)ss$/, '\1ss')
50
+ inflect.singular(/(.*)ies$/, '\1y')
51
+
52
+ inflect.irregular('person', 'people')
53
+ inflect.irregular('child', 'children')
54
+ inflect.irregular('sex', 'sexes')
55
+ inflect.irregular('move', 'moves')
56
+ inflect.irregular('tooth', 'teeth')
57
+ inflect.irregular('die', 'dice')
58
+ inflect.irregular('talisman', 'talismans')
59
+ inflect.irregular('penis', 'penises')
60
+ inflect.irregular('christmas', 'christmases')
61
+ inflect.irregular('knowledge', 'knowledge')
62
+ inflect.irregular('quiz', 'quizzes')
63
+ end
@@ -0,0 +1,99 @@
1
+ require 'singleton'
2
+ require File.join(File.dirname(__FILE__), "..", "english_extensions", 'inflect')
3
+ module Mack # :nodoc:
4
+ module Utils # :nodoc:
5
+ # This class is used to deal with inflection strings. This means taken a string and make it plural, or singular, etc...
6
+ # Inflection rules can be added very easy, and are checked from the bottom up. This means that the last rule is the first
7
+ # rule to be matched. The exception to this, kind of, is 'irregular' and 'uncountable' rules. The 'uncountable' rules are
8
+ # always checked first, then the 'irregular' rules, and finally either the 'singular' or 'plural' rules, depending on what
9
+ # you're trying to do. Within each of these sets of rules, the last rule in is the first rule matched.
10
+ #
11
+ # Example:
12
+ # Mack::Utils::Inflector.inflections do |inflect|
13
+ # inflect.plural(/$/, 's')
14
+ # inflect.plural(/^(ox)$/i, '\1en')
15
+ # inflect.plural(/(phenomen|criteri)on$/i, '\1a')
16
+ #
17
+ # inflect.singular(/s$/i, '')
18
+ # inflect.singular(/(n)ews$/i, '\1ews')
19
+ # inflect.singular(/^(.*)ookies$/, '\1ookie')
20
+ #
21
+ # inflect.irregular('person', 'people')
22
+ # inflect.irregular('child', 'children')
23
+ # end
24
+ class Inflector
25
+ include Singleton
26
+
27
+ # Adds a plural rule to the system.
28
+ #
29
+ # Example:
30
+ # Mack::Utils::Inflector.inflections do |inflect|
31
+ # inflect.plural(/$/, 's')
32
+ # inflect.plural(/^(ox)$/i, '\1en')
33
+ # inflect.plural(/(phenomen|criteri)on$/i, '\1a')
34
+ # end
35
+ def plural(rule, replacement)
36
+ English::Inflect.plural_rule(rule, replacement)
37
+ end
38
+
39
+ # Adds a singular rule to the system.
40
+ #
41
+ # Example:
42
+ # Mack::Utils::Inflector.inflections do |inflect|
43
+ # inflect.singular(/s$/i, '')
44
+ # inflect.singular(/(n)ews$/i, '\1ews')
45
+ # inflect.singular(/^(.*)ookies$/, '\1ookie')
46
+ # end
47
+ def singular(rule, replacement)
48
+ English::Inflect.singular_rule(rule, replacement)
49
+ end
50
+
51
+ # Adds a irregular rule to the system.
52
+ #
53
+ # Example:
54
+ # Mack::Utils::Inflector.inflections do |inflect|
55
+ # inflect.irregular('person', 'people')
56
+ # inflect.irregular('child', 'children')
57
+ # end
58
+ def irregular(rule, replacement)
59
+ English::Inflect.rule(rule, replacement)
60
+ English::Inflect.word(rule, replacement)
61
+ end
62
+
63
+ # Returns the singular version of the word, if possible.
64
+ #
65
+ # Examples:
66
+ # Mack::Utils::Inflector.instance.singularize("armies") # => "army"
67
+ # Mack::Utils::Inflector.instance.singularize("people") # => "person"
68
+ # Mack::Utils::Inflector.instance.singularize("boats") # => "boat"
69
+ def singularize(word)
70
+ English::Inflect.singular(word)
71
+ end
72
+
73
+ # Returns the singular version of the word, if possible.
74
+ #
75
+ # Examples:
76
+ # Mack::Utils::Inflector.instance.pluralize("army") # => "armies"
77
+ # Mack::Utils::Inflector.instance.pluralize("person") # => "people"
78
+ # Mack::Utils::Inflector.instance.pluralize("boat") # => "boats"
79
+ def pluralize(word)
80
+ English::Inflect.plural(word)
81
+ end
82
+
83
+ public
84
+ class << self
85
+
86
+ # Yields up Mack::Utils::Inflector.instance
87
+ def inflections
88
+ if block_given?
89
+ yield Mack::Utils::Inflector.instance
90
+ else
91
+ Mack::Utils::Inflector.instance
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ end # Inflection
98
+ end # Utils
99
+ end # Mack
@@ -0,0 +1,27 @@
1
+ module Mack
2
+ module Utils
3
+ class OptionMerger #:nodoc:
4
+ instance_methods.each do |method|
5
+ undef_method(method) if method !~ /^(__|instance_eval|class|object_id)/
6
+ end
7
+
8
+ def initialize(context, options)
9
+ @context, @options = context, options
10
+ end
11
+
12
+ private
13
+ def method_missing(method, *arguments, &block)
14
+ merge_argument_options! arguments
15
+ @context.send(method, *arguments, &block)
16
+ end
17
+
18
+ def merge_argument_options!(arguments)
19
+ arguments << if arguments.last.respond_to? :to_hash
20
+ @options.merge(arguments.pop)
21
+ else
22
+ @options.dup
23
+ end
24
+ end
25
+ end # OptionMerger
26
+ end # Utils
27
+ end # Mack
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mack-facets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.0
5
+ platform: ruby
6
+ authors:
7
+ - markbates
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-07-16 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: facets
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - "="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.4.1
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: english
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - "="
30
+ - !ruby/object:Gem::Version
31
+ version: 0.2.0
32
+ version:
33
+ description: "mack-facets was developed by: markbates"
34
+ email: mark@mackframework.com
35
+ executables: []
36
+
37
+ extensions: []
38
+
39
+ extra_rdoc_files:
40
+ - README
41
+ files:
42
+ - lib/english_extensions/inflect.rb
43
+ - lib/english_extensions/numerals.rb
44
+ - lib/extensions/array.rb
45
+ - lib/extensions/class.rb
46
+ - lib/extensions/hash.rb
47
+ - lib/extensions/kernel.rb
48
+ - lib/extensions/math.rb
49
+ - lib/extensions/module.rb
50
+ - lib/extensions/object.rb
51
+ - lib/extensions/string.rb
52
+ - lib/extensions/symbol.rb
53
+ - lib/mack-facets.rb
54
+ - lib/utils/inflections.rb
55
+ - lib/utils/inflector.rb
56
+ - lib/utils/options_merger.rb
57
+ - README
58
+ has_rdoc: true
59
+ homepage: http://www.mackframework.com
60
+ post_install_message:
61
+ rdoc_options: []
62
+
63
+ require_paths:
64
+ - lib
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: 1.8.6
71
+ version:
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ requirements: []
79
+
80
+ rubyforge_project: magrathea
81
+ rubygems_version: 1.1.1
82
+ signing_key:
83
+ specification_version: 2
84
+ summary: Ruby language extensions for Mack
85
+ test_files: []
86
+