rext 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/History.rdoc +97 -0
  2. data/Manifest +54 -0
  3. data/README.rdoc +136 -0
  4. data/Rakefile +16 -0
  5. data/benchmarks/enumerable.rb +14 -0
  6. data/benchmarks/proc.rb +24 -0
  7. data/lib/rext.rb +24 -0
  8. data/lib/rext/all.rb +18 -0
  9. data/lib/rext/array.rb +6 -0
  10. data/lib/rext/array/helpers.rb +64 -0
  11. data/lib/rext/date.rb +6 -0
  12. data/lib/rext/date/helpers.rb +11 -0
  13. data/lib/rext/enumerable.rb +6 -0
  14. data/lib/rext/enumerable/helpers.rb +88 -0
  15. data/lib/rext/hash.rb +6 -0
  16. data/lib/rext/hash/helpers.rb +42 -0
  17. data/lib/rext/integer.rb +6 -0
  18. data/lib/rext/integer/helpers.rb +29 -0
  19. data/lib/rext/module.rb +6 -0
  20. data/lib/rext/module/helpers.rb +85 -0
  21. data/lib/rext/numeric.rb +7 -0
  22. data/lib/rext/numeric/bytes.rb +16 -0
  23. data/lib/rext/numeric/time.rb +57 -0
  24. data/lib/rext/object.rb +7 -0
  25. data/lib/rext/object/helpers.rb +62 -0
  26. data/lib/rext/object/metaclass.rb +29 -0
  27. data/lib/rext/proc.rb +7 -0
  28. data/lib/rext/proc/helpers.rb +22 -0
  29. data/lib/rext/string.rb +7 -0
  30. data/lib/rext/string/encode.rb +82 -0
  31. data/lib/rext/string/helpers.rb +246 -0
  32. data/lib/rext/symbol.rb +6 -0
  33. data/lib/rext/symbol/helpers.rb +16 -0
  34. data/lib/rext/time.rb +6 -0
  35. data/lib/rext/time/helpers.rb +43 -0
  36. data/lib/rext/version.rb +4 -0
  37. data/rext.gemspec +30 -0
  38. data/spec/array_spec.rb +61 -0
  39. data/spec/date_spec.rb +14 -0
  40. data/spec/enumerable_spec.rb +55 -0
  41. data/spec/hash_spec.rb +36 -0
  42. data/spec/integer_spec.rb +19 -0
  43. data/spec/module_spec.rb +41 -0
  44. data/spec/numeric_spec.rb +31 -0
  45. data/spec/object_spec.rb +101 -0
  46. data/spec/spec.opts +1 -0
  47. data/spec/spec_helper.rb +5 -0
  48. data/spec/string_spec.rb +194 -0
  49. data/spec/symbol_spec.rb +14 -0
  50. data/spec/time_spec.rb +22 -0
  51. data/tasks/benchmark.rake +13 -0
  52. data/tasks/docs.rake +13 -0
  53. data/tasks/gemspec.rake +3 -0
  54. data/tasks/spec.rake +25 -0
  55. metadata +147 -0
@@ -0,0 +1,29 @@
1
+
2
+ class Object
3
+
4
+ ##
5
+ # Return the metaclass of this object.
6
+
7
+ def metaclass
8
+ class << self; self end
9
+ end
10
+
11
+ ##
12
+ # Evaluate a +string+ or +block+ in context to this
13
+ # object metaclass.
14
+
15
+ def meta_eval string = nil, &block
16
+ return metaclass.class_eval(string) if string
17
+ metaclass.class_eval &block
18
+ end
19
+ alias :metaeval :meta_eval
20
+
21
+ ##
22
+ # Define a singleton method.
23
+
24
+ def meta_def name, &block
25
+ meta_eval { define_method name, &block }
26
+ end
27
+ alias :metadef :meta_def
28
+
29
+ end
@@ -0,0 +1,7 @@
1
+
2
+
3
+ #--
4
+ # Load Proc specific rext extensions.
5
+ #++
6
+
7
+ require 'rext/proc/helpers'
@@ -0,0 +1,22 @@
1
+
2
+ class Proc
3
+
4
+ ##
5
+ # Yield or instance evaluate the +object+ passed
6
+ # based on this proc's arity.
7
+ #
8
+ # === Examples
9
+ #
10
+ # def foo &block
11
+ # block.yield_or_eval 'bar'
12
+ # end
13
+ #
14
+ # foo { |v| v.length } # => 3
15
+ # foo { length } # => 3
16
+ #
17
+
18
+ def yield_or_eval object
19
+ arity > 0 ? self.call(object) : object.instance_eval(&self)
20
+ end
21
+
22
+ end
@@ -0,0 +1,7 @@
1
+
2
+ #--
3
+ # Load String specific rext extensions.
4
+ #++
5
+
6
+ require 'rext/string/encode'
7
+ require 'rext/string/helpers'
@@ -0,0 +1,82 @@
1
+
2
+ require 'rack'
3
+ require 'digest/sha2'
4
+ require 'digest/md5'
5
+
6
+ class String
7
+
8
+ ##
9
+ # Return 32 character md5 string.
10
+ #
11
+ # === Examples
12
+ #
13
+ # 'test'.to_md5 # => 098f6bcd4621d373cade4e832627b4f6
14
+ #
15
+
16
+ def to_md5
17
+ ::Digest::MD5.hexdigest self
18
+ end
19
+
20
+ ##
21
+ # Return 128 character sha512 string.
22
+ #
23
+ # === Examples
24
+ #
25
+ # 'test'.to_sha512 # => ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff
26
+ #
27
+
28
+ def to_sha512
29
+ ::Digest::SHA512.hexdigest self
30
+ end
31
+
32
+ ##
33
+ # Return Base 64 decoded string.
34
+ #
35
+ # === Examples
36
+ #
37
+ # 'Y29va2llcw=='.base64_decode # => cookies
38
+ #
39
+
40
+ def base64_decode
41
+ unpack('m').first
42
+ end
43
+
44
+ ##
45
+ # Return Base 64 encoded string.
46
+ #
47
+ # === Examples
48
+ #
49
+ # 'cookies'.base64_encode # => Y29va2llcw==
50
+ #
51
+
52
+ def base64_encode
53
+ [self].pack('m').chop
54
+ end
55
+
56
+ ##
57
+ # URL encode. Shortcut for Rack::Utils.encode.
58
+
59
+ def url_encode
60
+ Rack::Utils.escape self
61
+ end
62
+
63
+ ##
64
+ # URL decode. Shortcut for Rack::Utils.unescape.
65
+
66
+ def url_decode
67
+ Rack::Utils.unescape self
68
+ end
69
+
70
+ ##
71
+ # Escape html entities. Shortcut for Rack::Utils.escape_html.
72
+ #
73
+ # === Examples
74
+ #
75
+ # 'im <strong>strong</strong>.escape_html # => im &lt;strong&gt;strong&lt;/strong&gt;
76
+ #
77
+
78
+ def escape_html
79
+ Rack::Utils.escape_html self
80
+ end
81
+
82
+ end
@@ -0,0 +1,246 @@
1
+
2
+ require 'extlib'
3
+
4
+ class String
5
+
6
+ ##
7
+ # Returns a File instance.
8
+ #
9
+ # === Examples
10
+ #
11
+ # 'History.rdoc'.file.mtime
12
+ #
13
+
14
+ def file
15
+ File.new self
16
+ end
17
+
18
+ ##
19
+ # Returns a Pathname instance.
20
+ #
21
+ # === Examples
22
+ #
23
+ # 'lib'.path.join('foo').expand_path
24
+ #
25
+
26
+ def path
27
+ require 'pathname'
28
+ Pathname.new self
29
+ end
30
+
31
+ ##
32
+ # Returns an array of files matching self.
33
+ #
34
+ # === Examples
35
+ #
36
+ # 'lib/**/*.rb'.files
37
+ #
38
+
39
+ def files
40
+ Dir[self]
41
+ end
42
+
43
+ ##
44
+ # Merge the +word+ passed into the string. This
45
+ # is useful for adding classes which may already
46
+ # exist in a string.
47
+ #
48
+ # === Examples
49
+ #
50
+ # 'product'.merge_word('sold') # => "product sold"
51
+ # 'product sold'.merge_word('sold') # => "product sold"
52
+ #
53
+
54
+ def merge_word word
55
+ self << " #{word}" unless split.include? word
56
+ self
57
+ end
58
+ alias :add_class :merge_word
59
+
60
+ ##
61
+ # Digitize a string.
62
+ #
63
+ # === Examples:
64
+ #
65
+ # '$100,000'.digitize # => 100000
66
+ #
67
+
68
+ def digitize
69
+ gsub /[^\d]/, ''
70
+ end
71
+
72
+ ##
73
+ # Returns a constant when the string is a valid constant name.
74
+
75
+ def constantize
76
+ Extlib::Inflection.constantize self
77
+ end
78
+
79
+ ##
80
+ # Convert a string to camel-case, and optionally +capitalize_first_letter+.
81
+
82
+ def camelize capitalize_first_letter = false
83
+ string = Extlib::Inflection.camelize(self)
84
+ return string if capitalize_first_letter
85
+ string[0,1] = string.first.downcase
86
+ string
87
+ end
88
+
89
+ ##
90
+ # Wrap a string with a +prefix+ and optional
91
+ # +suffix+. When the +suffix+ is not present
92
+ # the +prefix+ will be used.
93
+ #
94
+ # === Examples
95
+ #
96
+ # 'foo'.wrap('|') # => |foo|
97
+ # 'foo'.wrap('(', ')') # => (foo)
98
+ #
99
+
100
+ def wrap prefix, suffix = nil
101
+ prefix + self + (suffix || prefix)
102
+ end
103
+
104
+ ##
105
+ # Check if a string starts with another +string+.
106
+ #
107
+ # === Examples
108
+ #
109
+ # 'foo bar'.starts_with? 'foo' # => true
110
+ #
111
+
112
+ def starts_with? string
113
+ index(string) == 0
114
+ end
115
+
116
+ ##
117
+ # Check if a string ends with another +string+.
118
+ #
119
+ # === Examples
120
+ #
121
+ # 'foo bar'.ends_with? 'bar' # => true
122
+ #
123
+
124
+ def ends_with? string
125
+ rindex(string) == length - string.length
126
+ end
127
+
128
+ ##
129
+ # Determines if a string is plural.
130
+ #
131
+ # === Examples
132
+ #
133
+ # 'cookies'.plural? # => true
134
+ # 'cookie'.plural? # => false
135
+ #
136
+
137
+ def plural?
138
+ singular != self
139
+ end
140
+
141
+ ##
142
+ # Determines if a string is singular.
143
+ #
144
+ # === Examples
145
+ #
146
+ # 'cookies'.singular? # => false
147
+ # 'cookie'.singular? # => true
148
+ #
149
+
150
+ def singular?
151
+ not plural?
152
+ end
153
+
154
+ ##
155
+ # First +n+ character(s).
156
+ #
157
+ # === Examples
158
+ #
159
+ # 'foo'.first # => f
160
+ # 'foo'.first(2) # => fo
161
+ #
162
+
163
+ def first n = 1
164
+ self[0, n]
165
+ end
166
+
167
+ ##
168
+ # Last +n+ character(s).
169
+ #
170
+ # === Examples
171
+ #
172
+ # 'bar'.last # => r
173
+ # 'bar'.last(2) # => ar
174
+ #
175
+
176
+ def last n = 1
177
+ self[-n, n]
178
+ end
179
+
180
+ ##
181
+ # All characters after +n+.
182
+ #
183
+ # === Examples
184
+ #
185
+ # '.css'.from(1) #=> css
186
+ #
187
+
188
+ def from n
189
+ self[n, length]
190
+ end
191
+
192
+ ##
193
+ # Replace all underscores with hyphens.
194
+
195
+ def dasherize
196
+ tr '_', '-'
197
+ end
198
+
199
+ ##
200
+ # Return hash of word frequencies.
201
+ #
202
+ # === Examples
203
+ #
204
+ # 'foo foo bar'.word_frequency
205
+ # # => { 'foo' => 2, 'bar' => 1 }
206
+ #
207
+
208
+ def word_frequency
209
+ split.inject Hash.new(0) do |frequencies, word|
210
+ frequencies[word] += 1
211
+ frequencies
212
+ end
213
+ end
214
+
215
+ ##
216
+ # Return frequency of _word_ or 0.
217
+ #
218
+ # === Examples
219
+ #
220
+ # 'foo foo bar'.frequency_of_word('foo') # => 2
221
+ # 'foo foo bar'.frequency_of_word('bar') # => 1
222
+ #
223
+
224
+ def frequency_of_word word
225
+ word_frequency[word]
226
+ end
227
+
228
+ class InvalidSwitchError < StandardError; end
229
+
230
+ ##
231
+ # Returns the switch equivilant of this string.
232
+ #
233
+ # === Examples
234
+ #
235
+ # 'foo_bar'.switchify # => --foo-bar
236
+ # 'lots_of_foobar'.switchify # => --lots-of-foobar
237
+ # 't'.switchify # => -t
238
+ # ''.switchify # => InvalidSwitchError
239
+ #
240
+
241
+ def switchify
242
+ raise InvalidSwitchError, 'switch must have a length > 0' if length.zero?
243
+ length > 1 ? "--#{dasherize}" : "-#{self}"
244
+ end
245
+
246
+ end
@@ -0,0 +1,6 @@
1
+
2
+ #--
3
+ # Load Symbol specific rext extensions.
4
+ #++
5
+
6
+ require 'rext/symbol/helpers'
@@ -0,0 +1,16 @@
1
+
2
+ class Symbol
3
+
4
+ ##
5
+ # Return a proc which sends itself as a message
6
+ # to the first proc argument.
7
+ #
8
+ # === Examples
9
+ #
10
+ # %w( some foo bar ).map(&:length) # => [4, 3, 3]
11
+ #
12
+
13
+ def to_proc
14
+ Proc.new { |object| object.send self }
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+
2
+ #--
3
+ # Load Time specific rext extensions.
4
+ #++
5
+
6
+ require 'rext/time/helpers'
@@ -0,0 +1,43 @@
1
+
2
+ class Time
3
+
4
+ def to_time #:nodoc:
5
+ self
6
+ end
7
+
8
+ ##
9
+ # Time in words since +time+ or now.
10
+ #
11
+ # === Examples
12
+ #
13
+ # 5.seconds.ago.in_words_since_now # => less than one minute
14
+ # 5.days.ago.in_words_since_now # => 5 days
15
+ # 1.month.ago.in_words_since_now # => 1 month
16
+ # 101.years.ago.in_words_since_now # => hundreds of years
17
+ #
18
+ # "the article was published #{article.created_at.in_words_since_now} ago"
19
+ # # => the article was published 15 minutes ago
20
+ #
21
+
22
+ def in_words_since time = Time.now
23
+ return if self > time
24
+ seconds = (time - self).to_i
25
+ # TODO: abstract this out
26
+ pluralize = lambda do |type|
27
+ n = seconds.send(:"to_#{type}s")
28
+ n == 1 ? "one #{type}" : "#{n} #{type}s"
29
+ end
30
+ case seconds
31
+ when 0..59 ; 'less than one minute'
32
+ when 1.minute..59.minutes ; pluralize[:minute]
33
+ when 1.hour..23.hours ; pluralize[:hour]
34
+ when 1.day..6.days ; pluralize[:day]
35
+ when 1.week..3.weeks ; pluralize[:week]
36
+ when 1.month..11.months ; pluralize[:month]
37
+ when 1.year..99.years ; pluralize[:year]
38
+ else 'hundreds of years'
39
+ end
40
+ end
41
+ alias :in_words_since_now :in_words_since
42
+
43
+ end