epitools 0.5.7 → 0.5.8

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.7
1
+ 0.5.8
data/epitools.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "epitools"
8
- s.version = "0.5.7"
8
+ s.version = "0.5.8"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["epitron"]
12
- s.date = "2012-05-04"
12
+ s.date = "2012-07-08"
13
13
  s.description = "Miscellaneous utility libraries to make my life easier."
14
14
  s.email = "chris@ill-logic.com"
15
15
  s.extra_rdoc_files = [
@@ -87,7 +87,7 @@ Gem::Specification.new do |s|
87
87
  s.homepage = "http://github.com/epitron/epitools"
88
88
  s.licenses = ["WTFPL"]
89
89
  s.require_paths = ["lib"]
90
- s.rubygems_version = "1.8.21"
90
+ s.rubygems_version = "1.8.24"
91
91
  s.summary = "NOT UTILS... METILS!"
92
92
 
93
93
  if s.respond_to? :specification_version then
@@ -16,6 +16,7 @@ autoload :Open3, 'open3'
16
16
  autoload :Timeout, 'timeout'
17
17
  autoload :Find, 'find'
18
18
  autoload :Benchmark, 'benchmark'
19
+ autoload :Tracer, 'tracer'
19
20
  #autoload :DelegateClass, 'delegate'
20
21
 
21
22
  # YAML is sometimes loaded improperly.
@@ -3,13 +3,13 @@ require 'epitools'
3
3
  ## Alias "Enumerator" to "Enum"
4
4
 
5
5
  if RUBY_VERSION["1.8"]
6
- require 'enumerator'
6
+ require 'enumerator'
7
7
  Enumerator = Enumerable::Enumerator unless defined? Enumerator
8
8
  end
9
9
 
10
10
  unless defined? Enum
11
11
  if defined? Enumerator
12
- Enum = Enumerator
12
+ Enum = Enumerator
13
13
  else
14
14
  $stderr.puts "WARNING: Couldn't find the Enumerator class. Enum will not be available."
15
15
  end
@@ -25,7 +25,7 @@ class Object
25
25
  def self.alias_class_method(dest, src)
26
26
  metaclass.send(:alias_method, dest, src)
27
27
  end
28
-
28
+
29
29
  end
30
30
 
31
31
  require 'epitools/core_ext/object'
@@ -45,22 +45,31 @@ class MatchData
45
45
  def to_hash
46
46
  Hash[ names.zip(captures) ]
47
47
  end
48
-
48
+
49
49
  end
50
50
 
51
51
 
52
52
  class Binding
53
53
 
54
+ #
55
+ # Get a variables in this binding
56
+ #
54
57
  def [](key)
55
58
  eval(key.to_s)
56
59
  end
57
-
60
+
61
+ #
62
+ # Set a variable in this binding
63
+ #
58
64
  def []=(key, val)
59
65
  Thread.current[:_alter_binding_local_] = val
60
66
  eval("#{key} = Thread.current[:_alter_binding_local_]")
61
67
  Thread.current[:_alter_binding_local_] = nil
62
68
  end
63
69
 
70
+ #
71
+ # Return all the local variables in the binding
72
+ #
64
73
  def local_variables
65
74
  eval("local_variables")
66
75
  end
@@ -72,9 +81,14 @@ end
72
81
  class Proc
73
82
 
74
83
  #
75
- # Joins two procs together, returning a new proc.
84
+ # Chain two procs together, returning a new proc. Each proc is executed one after the other,
85
+ # with the same input arguments. The return value is an array of all the procs' return values.
76
86
  #
77
- # Example:
87
+ # You can use either the .join method, or the overloaded & operator.
88
+ #
89
+ # Examples:
90
+ # joined = proc1 & proc2
91
+ # joined = proc1.join proc2
78
92
  # newproc = proc { 1 } & proc { 2 }
79
93
  # newproc.call #=> [1, 2]
80
94
  #
@@ -83,7 +97,7 @@ class Proc
83
97
  proc { |*args| [self.call(*args), other.call(*args)] }
84
98
  end
85
99
  alias_method :&, :join
86
-
100
+
87
101
  #
88
102
  # Chains two procs together, returning a new proc. The output from each proc is passed into
89
103
  # the input of the next one.
@@ -96,14 +110,14 @@ class Proc
96
110
  other ||= block
97
111
  proc { |*args| other.call( self.call(*args) ) }
98
112
  end
99
- alias_method :|, :chain
100
-
113
+ alias_method :|, :chain
114
+
101
115
  end
102
116
 
103
117
 
104
118
  unless defined?(BasicObject)
105
119
  #
106
- # A BasicObject class for Ruby 1.8
120
+ # Backported BasicObject for Ruby 1.8
107
121
  #
108
122
  class BasicObject
109
123
  instance_methods.each { |m| undef_method m unless m =~ /^__/ }
@@ -112,15 +126,36 @@ end
112
126
 
113
127
 
114
128
 
129
+ class Object
130
+
131
+ #
132
+ # Negates a boolean, chained-method style.
133
+ #
134
+ # Example:
135
+ # >> 10.even?
136
+ # => true
137
+ # >> 10.not.even?
138
+ # => false
139
+ #
140
+ def not
141
+ NotWrapper.new(self)
142
+ end
143
+
144
+ end
145
+
115
146
  class NotWrapper < BasicObject # :nodoc:
116
147
  def initialize(orig)
117
148
  @orig = orig
118
149
  end
119
-
150
+
120
151
  def inspect
121
152
  "{NOT #{@orig.inspect}}"
122
153
  end
123
-
154
+
155
+ def is_a?(other)
156
+ other === self
157
+ end
158
+
124
159
  def method_missing(meth, *args, &block)
125
160
  result = @orig.send(meth, *args, &block)
126
161
  if result.is_a? ::TrueClass or result.is_a? ::FalseClass
@@ -131,35 +166,23 @@ class NotWrapper < BasicObject # :nodoc:
131
166
  end
132
167
  end
133
168
 
134
- class Object
135
-
136
- #
137
- # Negates a boolean, chained-method style.
138
- #
139
- # Example:
140
- # >> 10.even?
141
- # => true
142
- # >> 10.not.even?
143
- # => false
144
- #
145
- def not
146
- NotWrapper.new(self)
147
- end
148
-
149
- end
169
+
150
170
 
151
171
  unless IO.respond_to? :copy_stream
152
-
172
+
153
173
  class IO
154
-
174
+
175
+ #
176
+ # IO.copy_stream backport
177
+ #
155
178
  def self.copy_stream(input, output)
156
179
  while chunk = input.read(8192)
157
180
  output.write(chunk)
158
181
  end
159
182
  end
160
-
183
+
161
184
  end
162
-
185
+
163
186
  end
164
187
 
165
188
 
@@ -198,8 +221,37 @@ end
198
221
 
199
222
  module URI
200
223
 
224
+ #
225
+ # Return a Hash of the variables in the query string
226
+ #
201
227
  def params
202
228
  query.to_params
203
229
  end
204
230
 
231
+ end
232
+
233
+
234
+ class Time
235
+
236
+ #
237
+ # Which "quarter" of the year does this date fall into?
238
+ #
239
+ def quarter
240
+ (month / 3.0).ceil
241
+ end
242
+
243
+ end
244
+
245
+
246
+ #
247
+ # Give ObjectSpace Enumerable powers (select, map, etc.)
248
+ #
249
+ module ObjectSpace
250
+
251
+ include Enumerable
252
+
253
+ alias_method :each, :each_object
254
+
255
+ extend self
256
+
205
257
  end
@@ -7,9 +7,13 @@ class Array
7
7
  def squash
8
8
  flatten.compact.uniq
9
9
  end
10
-
10
+
11
+ #def to_hash
12
+ # Hash[self]
13
+ #end
14
+
11
15
  #
12
- # Removes the elements from the array for which the block evaluates to true.
16
+ # Removes the elements from the array for which the block evaluates to true.
13
17
  # In addition, return the removed elements.
14
18
  #
15
19
  # For example, if you wanted to split an array into evens and odds:
@@ -20,7 +24,7 @@ class Array
20
24
  #
21
25
  def remove_if(&block)
22
26
  removed = []
23
-
27
+
24
28
  delete_if do |x|
25
29
  if block.call(x)
26
30
  removed << x
@@ -29,29 +33,29 @@ class Array
29
33
  false
30
34
  end
31
35
  end
32
-
36
+
33
37
  removed
34
38
  end
35
-
39
+
36
40
  #
37
41
  # zip from the right (or reversed zip.)
38
42
  #
39
43
  # eg:
40
- # >> [5,39].rzip([:hours, :mins, :secs])
44
+ # >> [5,39].rzip([:hours, :mins, :secs])
41
45
  # => [ [:mins, 5], [:secs, 39] ]
42
46
  #
43
47
  def rzip(other)
44
48
  # That's a lotta reverses!
45
49
  reverse.zip(other.reverse).reverse
46
- end
47
-
50
+ end
51
+
48
52
  #
49
53
  # Pick the middle element.
50
54
  #
51
55
  def middle
52
56
  self[(size-1) / 2]
53
57
  end
54
-
58
+
55
59
  #
56
60
  # XOR operator
57
61
  #
@@ -67,7 +71,7 @@ class Array
67
71
  sort_by{rand}
68
72
  end
69
73
  end
70
-
74
+
71
75
  #
72
76
  # Pick (a) random element(s).
73
77
  #
@@ -81,15 +85,14 @@ class Array
81
85
  end
82
86
  end
83
87
  alias_method :pick, :sample
84
-
88
+
85
89
  #
86
90
  # Divide the array into n pieces.
87
91
  #
88
- def / pieces
92
+ def / pieces
89
93
  piece_size = (size.to_f / pieces).ceil
90
94
  each_slice(piece_size).to_a
91
95
  end
92
-
93
96
 
94
97
  alias_method :unzip, :transpose
95
98
 
@@ -316,3 +316,30 @@ module Enumerable
316
316
  end
317
317
 
318
318
 
319
+ class Enumerator
320
+
321
+ SPINNER = ['-', '\\', '|', '/']
322
+
323
+ #
324
+ # Display a spinner every `every` elements that pass through the Enumerator.
325
+ #
326
+ def with_spinner(every=37)
327
+ Enumerator.new do |yielder|
328
+ spins = 0
329
+
330
+ each.with_index do |e, i|
331
+ if i % every == 0
332
+ print "\b" unless spins == 0
333
+ print SPINNER[spins % 4]
334
+
335
+ spins += 1
336
+ end
337
+
338
+ yielder << e
339
+ end
340
+
341
+ print "\b \b" # erase the spinner when done
342
+ end
343
+ end
344
+
345
+ end
@@ -16,51 +16,60 @@ ASCII_PRINTABLE = (33..126)
16
16
  # 48: d2 b1 6d 31 3e 67 e1 88 99 8b 4b 34 1d 61 05 15 |..m1g....K4.a..|
17
17
  #
18
18
 
19
- def hexdump(data, options={})
20
- base_offset = options[:base_offset] || 0
21
- color = options[:color].nil? ? true : options[:color]
22
- highlight = options[:highlight]
23
-
24
- p options
25
- p color
26
-
27
- lines = data.scan(/.{1,16}/m)
28
- max_offset = (base_offset + data.size) / 16 * 16
29
- max_offset_width = max_offset.to_s.size
30
- max_hex_width = 3 * 16 + 1
31
-
32
- p [max_offset, max_offset_width]
33
- lines.each_with_index do |line,n|
34
- offset = base_offset + n*16
35
- bytes = line.unpack("C*")
36
- hex = bytes.map { |c| "%0.2x" % c }.insert(8, '').join(' ')
37
-
38
- plain = bytes.map do |c|
39
- if ASCII_PRINTABLE.include?(c)
40
- c = c.chr
41
- else
42
- color ? '<9>.</9>' : '.'
43
- end
44
- end.join('')
45
-
46
- if color
47
- outstring = "<light_cyan>%s<cyan>: <light_yellow>%s <default>|<light_white>%s<default>|" % [offset.to_s.ljust(max_offset_width), hex.ljust(max_hex_width), plain]
48
- outstring = outstring.colorize
49
- else
50
- outstring = "%s: %s |%s|" % [offset.to_s.ljust(max_offset_width), hex.ljust(max_hex_width), plain]
19
+
20
+ module Hex
21
+
22
+ DUMP_COLORS = Rash.new(
23
+ /\d/ => 13,
24
+ /\w/ => 3,
25
+ nil => 9,
26
+ :default => 7
27
+ )
28
+
29
+ def self.dump(data, options={})
30
+ base_offset = options[:base_offset] || 0
31
+ color = options[:color].nil? ? true : options[:color]
32
+ highlight = options[:highlight]
33
+
34
+ p options
35
+ p color
36
+
37
+ lines = data.scan(/.{1,16}/m)
38
+ max_offset = (base_offset + data.size) / 16 * 16
39
+ max_offset_width = max_offset.to_s.size
40
+ max_hex_width = 3 * 16 + 1
41
+
42
+ p [max_offset, max_offset_width]
43
+ lines.each_with_index do |line,n|
44
+ offset = base_offset + n*16
45
+ bytes = line.unpack("C*")
46
+ hex = bytes.map { |c| "%0.2x" % c }.insert(8, '').join(' ')
47
+
48
+ plain = bytes.map do |c|
49
+ if ASCII_PRINTABLE.include?(c)
50
+ c = c.chr
51
+ else
52
+ color ? '<9>.</9>' : '.'
53
+ end
54
+ end.join('')
55
+
56
+ puts "<11>#{offset.to_s.ljust(max_offset_width)}<3>: <14>#{hex.ljust(max_hex_width)} <8>|<15>#{plain}<8>|".colorize
51
57
  end
52
- puts outstring
53
- end
58
+ end
59
+
54
60
  end
55
61
 
62
+ def hexdump(*args)
63
+ Hex.dump(*args)
64
+ end
56
65
 
57
66
  if $0 == __FILE__
58
67
  data = (0..64).map{ rand(255).chr }.join('')
59
- hexdump(data)
68
+ Hex.dump(data)
60
69
  puts
61
- hexdump(data, :color=>false)
70
+ Hex.dump(data, :color=>false)
62
71
  puts
63
-
72
+
64
73
  data = "1234567890"*10
65
- hexdump(data)
74
+ Hex.dump(data)
66
75
  end