extra 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ require 'extra/array'
2
+ require 'extra/class'
3
+ require 'extra/enumerable'
4
+ require 'extra/file'
5
+ require 'extra/module'
6
+ require 'extra/numeric'
7
+ require 'extra/object'
8
+ require 'extra/objectspace'
9
+ require 'extra/openstruct'
10
+ require 'extra/string'
11
+ require 'extra/symbol'
@@ -0,0 +1,46 @@
1
+ class Array
2
+ # Thanks to manveru for this fun code :)
3
+ # All it does is flip the first and last elements. Pretty cool, eh? :)
4
+ #
5
+ # Example: <tt>[1, 2, 3, 4].flipflop #=> [4, 2, 3, 1]</tt>
6
+ #
7
+ # Returns: Array
8
+ #
9
+ def flipflop
10
+ if size > 1
11
+ [last] + self[1...-1] + [first]
12
+ else
13
+ self
14
+ end
15
+ end
16
+
17
+ # Destructive version of Array#flipflop.
18
+ #
19
+ # Returns: Array or nil
20
+ #
21
+ def flipflop!
22
+ if size > 1
23
+ a, b = shift, pop
24
+ unshift(b); push(a)
25
+ end
26
+ end
27
+
28
+ # Similar to String#nothing?, except it joins all the elements first and does
29
+ # the same check.
30
+ #
31
+ # Example: <tt>[" ", " ", ""].nothing? #=> true<tt>
32
+ #
33
+ # Returns: True or false.
34
+ #
35
+ def nothing?
36
+ join('').strip.empty?
37
+ end
38
+
39
+ # Check if the array contains any instances of a specific class.
40
+ #
41
+ # Example: <tt>['foo', 1, :bar].contains? Symbol #=> true</tt>
42
+ #
43
+ def contains?(klass)
44
+ map { |obj| obj.class }.include? klass
45
+ end
46
+ end
@@ -0,0 +1,23 @@
1
+ class Class
2
+ # Get all instances of this class that exist in ObjectSpace.
3
+ #
4
+ # Example: <tt>Module.instances #=> [Marshal, ObjectSpace, GC, Math, ...]</tt>
5
+ #
6
+ # Returns: Array
7
+ #
8
+ def instances
9
+ objects = []; ObjectSpace.each_object(self) { |obj| objects << obj }; objects
10
+ end
11
+
12
+ # Check whether the class has the parent `klass'.
13
+ #
14
+ # Example: <tt>Module.has_parent?(Object) #=> true</tt>
15
+ #
16
+ # Returns: True or false
17
+ #
18
+ def ancestor?(klass)
19
+ ancestors[1..-1].include? klass
20
+ end
21
+
22
+ alias parent? ancestor?
23
+ end
@@ -0,0 +1,55 @@
1
+ module Enumerable
2
+ # Get a hash representation of an array. The number of flattened array elements
3
+ # has to be even in order for this to work.
4
+ #
5
+ # Example: <tt>[:foo, :bar, :baz, :qux].to_hash #=> {:foo => :bar, :baz => :qux}</tt>
6
+ #
7
+ # Returns: Hash object
8
+ #
9
+ def to_hash
10
+ Hash[*to_a.flatten]
11
+ end
12
+
13
+ # Shorthand to get the size of the enumerable object in an array state.
14
+ #
15
+ # Example: <tt>+[:a, :b, :c] #=> 3</tt>
16
+ #
17
+ # Returns: Integer size
18
+ #
19
+ def +@
20
+ to_a.size
21
+ end
22
+
23
+ # Get a random element from the array.
24
+ #
25
+ # Example: <tt>[:a, :b, :c].random #=> :b</tt>
26
+ #
27
+ # Returns: Random object(s) or nil.
28
+ #
29
+ def random(how_many = 1)
30
+ objects = {}
31
+ array = to_a
32
+
33
+ # Let's just skip to nil if more than existent entries was requested.
34
+ return if array.size < how_many
35
+
36
+ # This is a longer, more efficient way than sorting the entire array.
37
+ how_many.times do
38
+ index = rand(array.size)
39
+ redo if objects.keys.include? index
40
+ objects[index] = array[index]
41
+ end
42
+
43
+ how_many == 1 ? objects.values[0] : objects.values
44
+ end
45
+
46
+ # Randomly replaces an object in the array.
47
+ #
48
+ # Example: <tt>a = [1, 2, 3]; a.random = 256; a #=> [256, 2, 3]</tt>
49
+ #
50
+ # Returns: Object
51
+ #
52
+ def random=(obj)
53
+ array, array[rand(array.size)] = to_a, obj
54
+ end
55
+ end
@@ -0,0 +1,14 @@
1
+ class File
2
+ # Windows vs. *nix directory separator.
3
+ DIRECTOY_SEPARTOR = RUBY_PLATFORM =~ /win32/ ? '\\' : '/'
4
+
5
+ # Shortcut for quickly writing to a file.
6
+ #
7
+ # Example: <tt>File.write('foo.txt', 'rawr') #=> 4</tt>
8
+ #
9
+ # Returns: Bytes written
10
+ #
11
+ def self.write(filename, contents)
12
+ File.open(filename, 'w') { |f| f.write(contents) }
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ class Module
2
+ # Go through each defined class in the module. Credit to apeiros for this =)
3
+ #
4
+ def each_class
5
+ constants.each { |constant_name|
6
+ constant = const_get(constant_name.intern)
7
+ yield constant if constant.class == Class && constant.name =~ /#{self.name}/
8
+ }
9
+ end
10
+
11
+ # List classes within a module. Thanks to apeiros for this.
12
+ #
13
+ # Example: <tt>Class.classes #=> [TrueClass, FalseClass, NilClass, Class]</tt>
14
+ #
15
+ # Returns: Array
16
+ #
17
+ def classes
18
+ list = []
19
+ each_class { |class_constant|
20
+ list << class_constant
21
+ }
22
+ return list
23
+ end
24
+ end
@@ -0,0 +1,82 @@
1
+ # See the math module, as methods from Math were added in Numeric dynamically.
2
+ #
3
+ class Numeric
4
+ # Credit to manveru for this code.
5
+ # Checks whether a number is even.
6
+ #
7
+ # Example:
8
+ #
9
+ # <tt> 5.even? #=> false</tt>
10
+ #
11
+ # <tt> 2.even? #=> true</tt>
12
+ #
13
+ # Returns: True or false
14
+ #
15
+ def even?
16
+ self % 2 == 0
17
+ end
18
+
19
+ # Credit to manveru for this code.
20
+ # Checks whether a number is odd.
21
+ #
22
+ # Example:
23
+ #
24
+ # <tt> 5.odd? #=> true</tt>
25
+ #
26
+ # <tt> 2.odd? #=> false</tt>
27
+ #
28
+ # Returns: True or false
29
+ #
30
+ def odd?
31
+ self % 2 != 0
32
+ end
33
+
34
+ # Checks whether a number is a negative number.
35
+ # Example: <tt>-4.negative? #=> true</tt>
36
+ #
37
+ # Returns: True or false
38
+ #
39
+ def negative?
40
+ self < 0
41
+ end
42
+
43
+ # Checks whether a number is positive. Here we will consider zero as being
44
+ # a positive number.
45
+ #
46
+ # Example: <tt>5.positive? #=> true</tt>
47
+ #
48
+ # Returns: True or false
49
+ #
50
+ def positive?
51
+ self >= 0
52
+ end
53
+
54
+ # Add commas every 3 spots in a number.
55
+ #
56
+ # Example: <tt>(4569810.12).format #=> 4,569,810.12</tt>
57
+ #
58
+ # Returns: Commatized string
59
+ #
60
+ def format(comma = ',', decimal = '.')
61
+ to_s.reverse.scan(/(?:-?\d{1,3}(?:\.\d{1,3})?-?)/).map { |s| s.sub('.', decimal) }.join(comma).reverse
62
+ end
63
+
64
+ # Credit to apeiros for this method.
65
+ #
66
+ # Min/max method.
67
+ #
68
+ # Example: <tt>-2.crop(0..1) # => 0</tt>
69
+ #
70
+ # Returns: Numeric
71
+ #
72
+ def crop(range_or_min, max=nil)
73
+ range = max ? range_or_min..max : range_or_min
74
+ if range.include?(self)
75
+ self
76
+ elsif self < range.first
77
+ range.first
78
+ else
79
+ range.last
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,88 @@
1
+ class Object
2
+ # whytheluckystiff: http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
3
+ #
4
+ # Gets a metaclass (a class of a class).
5
+ #
6
+ # Example: <tt>'hello'.metaclass #=> #<Class:#<String:0xb7a57998>></tt>
7
+ #
8
+ # Returns: The metaclass.
9
+ #
10
+ def metaclass
11
+ class << self; self; end
12
+ end
13
+
14
+ # whytheluckystiff: http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
15
+ #
16
+ # Evaluate code on the metaclass.
17
+ #
18
+ # Example:
19
+ #
20
+ # <tt> s = 'foo'; s.meta_eval { define_method(:longer) { self * 2 } }</tt>
21
+ #
22
+ # <tt> s.longer #=> "foofoo"'</tt>
23
+ #
24
+ # Returns: The block's final expression.
25
+ #
26
+ def meta_eval(&block)
27
+ metaclass.instance_eval(&block)
28
+ end
29
+
30
+ # whytheluckystiff: http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
31
+ #
32
+ # Define an instance method on the metaclass.
33
+ #
34
+ # Example: <tt>s = 'foo'; s.meta_def(:longer) { self * 2 }; s.longer #=> "foofoo"</tt>
35
+ #
36
+ # Returns: A Proc object of the method.
37
+ #
38
+ def meta_def(name, &block)
39
+ meta_eval { define_method(name, &block) }
40
+ end
41
+
42
+ # whytheluckystiff: http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
43
+ #
44
+ # Adds a class instance method.
45
+ #
46
+ # Example:
47
+ #
48
+ # <tt> SomeClass.class_def(:whoami) { 'I am SomeClass, silly!' }</tt>
49
+ #
50
+ # <tt> SomeClass.whoami #=> "I am SomeClass, silly!"</tt>
51
+ #
52
+ # Returns: A Proc object of the method, or nil.
53
+ #
54
+ def class_def(name, &block)
55
+ class_eval { define_method(name, &block) } if kind_of? Class
56
+ end
57
+
58
+ # Credit to the original author. This method retrieves a deep copy of the
59
+ # current object.
60
+ #
61
+ # Returns: Deep copy of the same object.
62
+ #
63
+ def deepcopy
64
+ Marshal.load(Marshal.dump(self))
65
+ end
66
+
67
+ # Convert object to boolean.
68
+ #
69
+ # Example:
70
+ #
71
+ # <tt> "foo".to_bool #=> true</tt>
72
+ #
73
+ # <tt> false.to_bool #=> false</tt>
74
+ #
75
+ # <tt> nil.to_bool #=> nil</tt>
76
+ #
77
+ # <tt> true.to_bool #=> true</tt>
78
+ #
79
+ # Returns: Boolean or nil.
80
+ #
81
+ def to_bool
82
+ if [FalseClass, NilClass].include? self.class
83
+ self
84
+ else
85
+ true
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,5 @@
1
+ module ObjectSpace
2
+ class << self
3
+ include Enumerable; alias each each_object
4
+ end
5
+ end
@@ -0,0 +1,20 @@
1
+ require 'ostruct'
2
+
3
+ class OpenStruct
4
+ # Gets the open struct hash.
5
+ #
6
+ # Returns: Hash
7
+ #
8
+ def to_hash
9
+ @table
10
+ end
11
+
12
+ # Get the YAML representation of the struct.
13
+ #
14
+ # Returns: YAML string
15
+ #
16
+ def to_yaml(*args)
17
+ require 'yaml'
18
+ to_hash.to_yaml(*args)
19
+ end
20
+ end
@@ -0,0 +1,229 @@
1
+ class String
2
+ # Generate a random string with a given length and seed.
3
+ #
4
+ # Example: <tt>String.random(4, 'abcdefg') #=> "cdeg"</tt>
5
+ #
6
+ # Returns: String
7
+ #
8
+ def self.random(length = 8, seed = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
9
+ s = ''; length.times { s << seed.shuffle[0] }; s
10
+ end
11
+
12
+ # Randomly shuffle a string.
13
+ #
14
+ # Example: <tt>'foobar'.shuffle #=> bofoar</tt>
15
+ #
16
+ # Returns: String
17
+ #
18
+ def shuffle
19
+ split(//u).sort_by { rand }.join('')
20
+ end
21
+
22
+ # Destructive version of String#shuffle.
23
+ #
24
+ # Returns: String or nil
25
+ #
26
+ def shuffle!
27
+ shuffled = shuffle
28
+ self[0..-1] = shuffled unless shuffled == self
29
+ end
30
+
31
+ # The ugly and well... unneeded Pythonic join method. Thanks to manveru for
32
+ # pointing out the interesting way of using array expansion with a combination
33
+ # of Array#flatten to support multiple arguments.
34
+ #
35
+ # Example: <tt>', '.join([1, 2, 3]) #=> "1, 2, 3"</tt>
36
+ #
37
+ # Returns: The joined string.
38
+ #
39
+ def join(*arr)
40
+ arr.flatten.join(self)
41
+ end
42
+
43
+ # Convenience method for things such as array mapping. This is identical to
44
+ # the version in Symbol.
45
+ #
46
+ # Example: <tt>[1, 2, 3].map(&'succ') #=> [2, 3, 4]</tt>
47
+ #
48
+ # Returns: Proc object
49
+ #
50
+ def to_proc
51
+ proc { |obj| obj.__send__(self) }
52
+ end
53
+
54
+ # For anyone who still misses PHP or Python's ord() functions... which I've
55
+ # learned to not need in Ruby, here it is.
56
+ #
57
+ # Example: <tt>'a'.ord #=> 97</tt>
58
+ #
59
+ # Returns: Fixnum or nil
60
+ #
61
+ def ord
62
+ self[0]
63
+ end
64
+
65
+ # Split string into an array of characters. Should be multi-byte safe...
66
+ #
67
+ # Example: <tt>'foo'.chars #=> ["f", "o", "o"]</tt>
68
+ #
69
+ # Returns: Array
70
+ #
71
+ def chars
72
+ split(//u)
73
+ end
74
+
75
+ # Capitalize words.
76
+ # Example: <tt>'The dog is stupid'.capitalize_words('is') #=> "The Dog is Stupid"</tt>
77
+ #
78
+ # Returns: String with words capitalized.
79
+ #
80
+ def capitalize_words(*disclude)
81
+ disclude = disclude.flatten
82
+ gsub(/\w+/u) { |word| disclude.include?(word) ? word : word.capitalize }
83
+ end
84
+
85
+ # My unsubmitted answer to a previous RubyQuiz question. Basically #munge will
86
+ # take words, scramble only the middle contents of the word while the first and
87
+ # last letters remain intact.
88
+ #
89
+ # Example: <tt>'You look like a terrifying goblin'.munge #=> "You look lkie a tiifyenrrg goilbn"</tt>
90
+ #
91
+ # Returns: Munged string
92
+ #
93
+ def munge
94
+ gsub(/\w+/u) do |word|
95
+ if word.size > 2
96
+ word[0,1] + word[1...-1].shuffle + word[-1,1]
97
+ else
98
+ word
99
+ end
100
+ end
101
+ end
102
+
103
+ # Destructive version of String#munge.
104
+ #
105
+ # Returns: Munged string or nil.
106
+ #
107
+ def munge!
108
+ munged = munge
109
+ self[0..-1] = munged unless munged == self
110
+ end
111
+
112
+ # Truncate a string to a certain length, and optionally append ending characters
113
+ # to it.
114
+ #
115
+ # Example: <tt>'foobarbaz'.truncate(3, '...') #=> "foo..."</tt>
116
+ #
117
+ # Returns: String
118
+ #
119
+ def truncate(length, ending = '')
120
+ if size > length
121
+ self[0...length] + ending
122
+ else
123
+ self
124
+ end
125
+ end
126
+
127
+ # Destructive version of String#truncate.
128
+ #
129
+ # Returns: String or nil
130
+ #
131
+ def truncate!(length, ending = '')
132
+ self[0..-1] = truncate if size > length
133
+ end
134
+
135
+ # Camelize string.
136
+ #
137
+ # Example: <tt>'what is my name'.camelcase #=> "whatIsMyName"</tt>
138
+ #
139
+ # Returns: String
140
+ #
141
+ def camelcase(cap_first = false)
142
+ if size > 1
143
+ camelcased = capitalize_words.gsub(/[^a-z]/i, '')
144
+ camelcased[0,1] = camelcased[0,1].downcase unless cap_first
145
+ else
146
+ self
147
+ end
148
+ end
149
+
150
+ # Destructive version of String#camelcase.
151
+ #
152
+ # Returns: String or nil.
153
+ #
154
+ def camelcase!(cap_first = false)
155
+ camelcased = camelcase(cap_first)
156
+ self[0..-1] = camelcased unless camelcased == self
157
+ end
158
+
159
+ # Removes everything except letters and spaces, replaces spaces with an
160
+ # underscore, and lowercases the string. The opposite of the camelcase convention.
161
+ #
162
+ # Example: <tt>"foo bar baz".underscore #=> "foo_bar_baz"</tt>
163
+ #
164
+ # Returns: String
165
+ #
166
+ def underscore
167
+ gsub(/[^a-z ]+/, '').gsub(/ +/, '_').downcase
168
+ end
169
+
170
+ # Destructive version of String#underscore.
171
+ #
172
+ # Returns: String or nil.
173
+ #
174
+ def underscore!
175
+ underscored = underscore
176
+ self[0..-1] = underscored unless underscored == self
177
+ end
178
+
179
+ # Convert a string to a Regexp object.
180
+ #
181
+ # Example: <tt>'foo'.to_rxp #=> /foo/</tt>
182
+ #
183
+ # Returns: Regexp object
184
+ #
185
+ def to_rxp
186
+ Regexp.new(self)
187
+ end
188
+
189
+ # Get an array of "words".
190
+ #
191
+ # Example: <tt>"hello, world!".words #=> ["hello", "world"]</tt>
192
+ #
193
+ # Returns: Array
194
+ #
195
+ def words
196
+ scan(/\w+/u)
197
+ end
198
+
199
+ # Wrap string by characters and join them by a specified separator.
200
+ #
201
+ # Example: <tt>"1234".wrap(2) #=> "12\n34"</tt>
202
+ #
203
+ # Returns: String
204
+ #
205
+ def wrap(width = 80, separator = $/)
206
+ scan(/.{1,#{width}}/u).join(separator)
207
+ end
208
+
209
+ # Destructive version of String#wrap.
210
+ #
211
+ # Returns: String or nil
212
+ #
213
+ def wrap!(width = 80, separator = $/)
214
+ wrapped = wrap(width, separator)
215
+ self[0..-1] = wrapped unless wrapped == self
216
+ end
217
+
218
+ # Checks if a string is nothing but whitespace or is empty.
219
+ #
220
+ # Example: <tt>" ".nothing? #=> true</tt>
221
+ #
222
+ # Returns: True or false
223
+ #
224
+ def nothing?
225
+ strip.empty?
226
+ end
227
+
228
+ alias +@ size
229
+ end
@@ -0,0 +1,13 @@
1
+ class Symbol
2
+ # Credit to whomever posted this on the mailing list :)
3
+ #
4
+ # Convenience method for things such as array mapping.
5
+ #
6
+ # Example: <tt>[1, 2, 3].map(&:succ) #=> [2, 3, 4]<tt>
7
+ #
8
+ # Returns: Proc object
9
+ #
10
+ def to_proc
11
+ proc { |obj| obj.__send__(self) }
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: extra
5
+ version: !ruby/object:Gem::Version
6
+ version: "1.0"
7
+ date: 2006-05-11 00:00:00 +09:00
8
+ summary: Adds useful methods to built-in/core Ruby classes and modules.
9
+ require_paths:
10
+ - lib
11
+ email: shugotenshi@gmail.com
12
+ homepage: http://ruby-extra.rubyforge.org
13
+ rubyforge_project: ruby-extra
14
+ description: `ruby-extra' is a package full of simple/fun/useful methods that are added to the core classes and modules of Ruby. It is quite similar to Facets but is still minimal.
15
+ autorequire: extra
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ authors:
29
+ - Matthew Harris
30
+ files:
31
+ - lib/extra.rb
32
+ - lib/extra/numeric.rb
33
+ - lib/extra/array.rb
34
+ - lib/extra/file.rb
35
+ - lib/extra/enumerable.rb
36
+ - lib/extra/openstruct.rb
37
+ - lib/extra/objectspace.rb
38
+ - lib/extra/class.rb
39
+ - lib/extra/module.rb
40
+ - lib/extra/symbol.rb
41
+ - lib/extra/object.rb
42
+ - lib/extra/string.rb
43
+ test_files: []
44
+
45
+ rdoc_options: []
46
+
47
+ extra_rdoc_files: []
48
+
49
+ executables: []
50
+
51
+ extensions: []
52
+
53
+ requirements: []
54
+
55
+ dependencies: []
56
+