rext 0.3.4

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.
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