epitools 0.5.103 → 0.5.105
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.
- checksums.yaml +4 -4
- data/README.rdoc +1 -1
- data/Rakefile +2 -2
- data/TODO +1 -1
- data/VERSION +1 -1
- data/lib/epitools.rb +1 -1
- data/lib/epitools/colored.rb +25 -25
- data/lib/epitools/core_ext/enumerable.rb +1 -1
- data/lib/epitools/core_ext/file.rb +6 -2
- data/lib/epitools/core_ext/hash.rb +43 -29
- data/lib/epitools/core_ext/misc.rb +21 -1
- data/lib/epitools/core_ext/object.rb +19 -19
- data/lib/epitools/core_ext/truthiness.rb +5 -5
- data/lib/epitools/daemonize.rb +1 -1
- data/lib/epitools/hexdump.rb +1 -1
- data/lib/epitools/iter.rb +26 -26
- data/lib/epitools/lcs.rb +3 -3
- data/lib/epitools/mimemagic.rb +7 -7
- data/lib/epitools/niceprint.rb +18 -18
- data/lib/epitools/numwords.rb +34 -34
- data/lib/epitools/path.rb +7 -0
- data/lib/epitools/permutations.rb +9 -9
- data/lib/epitools/pretty_backtrace.rb +11 -11
- data/lib/epitools/progressbar.rb +7 -7
- data/lib/epitools/rails.rb +2 -2
- data/lib/epitools/rash.rb +16 -16
- data/lib/epitools/ratio.rb +1 -1
- data/lib/epitools/sys.rb +47 -47
- data/lib/epitools/trie.rb +4 -4
- data/lib/epitools/typed_struct.rb +5 -5
- data/lib/epitools/wm.rb +6 -6
- data/lib/epitools/zopen.rb +2 -2
- data/spec/autoreq_spec.rb +5 -5
- data/spec/browser_spec.rb +1 -1
- data/spec/colored_spec.rb +5 -5
- data/spec/core_ext_spec.rb +1 -1
- data/spec/histogram_spec.rb +3 -3
- data/spec/iter_spec.rb +16 -16
- data/spec/lcs_spec.rb +5 -5
- data/spec/numwords_spec.rb +8 -8
- data/spec/permutations_spec.rb +9 -9
- data/spec/rash_spec.rb +7 -7
- data/spec/ratio_spec.rb +5 -5
- data/spec/sys_spec.rb +6 -6
- data/spec/term_spec.rb +7 -7
- data/spec/typed_struct_spec.rb +5 -5
- data/spec/wm_spec.rb +4 -4
- data/spec/zopen_spec.rb +11 -11
- metadata +2 -2
@@ -209,6 +209,26 @@ module URI
|
|
209
209
|
|
210
210
|
end
|
211
211
|
|
212
|
+
#
|
213
|
+
# Stupid workaround for URI blowing up when it receives a [ or ] character
|
214
|
+
#
|
215
|
+
module Better_URI_RFC3986_Parser # ::RFC3986_relative_ref
|
216
|
+
ESCAPE_ME_PLZ = "[]{}!"
|
217
|
+
|
218
|
+
def split(uri)
|
219
|
+
subsitutions = ESCAPE_ME_PLZ.chars.map { |c| [c, CGI.escape(c)] }
|
220
|
+
subsitutions << [" ", "%20"]
|
221
|
+
|
222
|
+
subsitutions.each do |find, replace|
|
223
|
+
uri = uri.gsub(find, replace)
|
224
|
+
end
|
225
|
+
|
226
|
+
super(uri)
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
URI::RFC3986_Parser.prepend(Better_URI_RFC3986_Parser)
|
212
232
|
|
213
233
|
|
214
234
|
class Time
|
@@ -271,4 +291,4 @@ class FalseClass
|
|
271
291
|
def present?
|
272
292
|
false
|
273
293
|
end
|
274
|
-
end
|
294
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class Object
|
2
2
|
|
3
3
|
#
|
4
|
-
# Return a hash of local variables in the caller's scope: {:variable_name=>value}
|
4
|
+
# Return a hash of local variables in the caller's scope: {:variable_name=>value}
|
5
5
|
#
|
6
6
|
def locals
|
7
7
|
require 'binding_of_caller'
|
@@ -10,7 +10,7 @@ class Object
|
|
10
10
|
vals = caller.eval("[ #{vars.join(",")} ]")
|
11
11
|
Hash[ vars.zip(vals) ]
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
|
15
15
|
#
|
16
16
|
# Gives you a copy of the object with its attributes changed to whatever was
|
@@ -35,7 +35,7 @@ class Object
|
|
35
35
|
# => 5
|
36
36
|
#
|
37
37
|
# Good for chaining lots of operations together in a REPL.
|
38
|
-
#
|
38
|
+
#
|
39
39
|
def with(options={})
|
40
40
|
if block_given?
|
41
41
|
yield self
|
@@ -60,7 +60,7 @@ class Object
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
#
|
65
65
|
# Return a copy of the class with modules mixed into it.
|
66
66
|
#
|
@@ -78,14 +78,14 @@ class Object
|
|
78
78
|
# Cache (memoize) the result of an instance method the first time
|
79
79
|
# it's called, storing this value in the "@methodname" instance variable,
|
80
80
|
# and always return this value on subsequent calls.
|
81
|
-
#
|
81
|
+
#
|
82
82
|
def self.memoize(*methods)
|
83
83
|
methods.each do |meth|
|
84
84
|
old_method = instance_method(meth)
|
85
85
|
|
86
86
|
if old_method.arity == 0
|
87
87
|
ivarname = "@#{meth}"
|
88
|
-
|
88
|
+
|
89
89
|
define_method meth do
|
90
90
|
instance_variable_get(ivarname) or instance_variable_set(ivarname, old_method.bind(self).call)
|
91
91
|
end
|
@@ -105,14 +105,14 @@ class Object
|
|
105
105
|
|
106
106
|
#
|
107
107
|
# Serialize this object to YAML.
|
108
|
-
#
|
108
|
+
#
|
109
109
|
def to_yaml
|
110
110
|
YAML::dump(self)
|
111
111
|
end
|
112
|
-
|
112
|
+
|
113
113
|
#
|
114
114
|
# Serialize this object to JSON (defaults to "pretty" indented JSON).
|
115
|
-
#
|
115
|
+
#
|
116
116
|
def to_json(pretty=true)
|
117
117
|
pretty ? JSON::pretty_generate(self) : JSON.dump(self)
|
118
118
|
end
|
@@ -130,7 +130,7 @@ class Object
|
|
130
130
|
end
|
131
131
|
end
|
132
132
|
end
|
133
|
-
|
133
|
+
|
134
134
|
#
|
135
135
|
# Time a block.
|
136
136
|
#
|
@@ -138,12 +138,12 @@ class Object
|
|
138
138
|
start = Time.now
|
139
139
|
result = yield
|
140
140
|
elapsed = Time.now - start
|
141
|
-
|
141
|
+
|
142
142
|
print "[#{message}] " if message
|
143
143
|
puts "elapsed time: %0.5fs" % elapsed
|
144
144
|
result
|
145
145
|
end
|
146
|
-
|
146
|
+
|
147
147
|
#
|
148
148
|
# Quick and easy benchmark.
|
149
149
|
#
|
@@ -156,13 +156,13 @@ class Object
|
|
156
156
|
# bench fast: ->{ fast_method }, slow: ->{ slow_method }
|
157
157
|
#
|
158
158
|
def bench(*args, &block)
|
159
|
-
|
159
|
+
|
160
160
|
# Shitty perl-esque hack to let the method take all the different kind of arguments.
|
161
161
|
opts = Hash === args.last ? args.pop : {}
|
162
162
|
n = args.first || 100
|
163
|
-
|
163
|
+
|
164
164
|
if opts.any?
|
165
|
-
|
165
|
+
|
166
166
|
raise "Error: Supply either a do/end block, or procs as options. Not both." if block_given?
|
167
167
|
raise "Error: Options must be procs." unless opts.all? { |k, v| v.is_a?(Proc) }
|
168
168
|
|
@@ -171,17 +171,17 @@ class Object
|
|
171
171
|
bm.report(name.to_s) { n.times &blk }
|
172
172
|
end
|
173
173
|
end
|
174
|
-
|
174
|
+
|
175
175
|
elsif block_given?
|
176
|
-
|
176
|
+
|
177
177
|
benchblock = proc do |bm|
|
178
178
|
bm.report { n.times &block }
|
179
179
|
end
|
180
|
-
|
180
|
+
|
181
181
|
else
|
182
182
|
raise "Error: Must supply some code to benchmark."
|
183
183
|
end
|
184
|
-
|
184
|
+
|
185
185
|
puts "* Benchmarking #{n} iterations..."
|
186
186
|
Benchmark.bmbm(&benchblock)
|
187
187
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
|
2
2
|
class Object
|
3
|
-
|
3
|
+
|
4
4
|
#
|
5
5
|
# Default "integer?" behaviour.
|
6
6
|
#
|
7
7
|
def integer?; false; end
|
8
|
-
|
8
|
+
|
9
9
|
#
|
10
10
|
# Default "float?" behaviour.
|
11
11
|
#
|
@@ -26,7 +26,7 @@ class Object
|
|
26
26
|
not nil?
|
27
27
|
end
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
end
|
31
31
|
|
32
32
|
|
@@ -50,7 +50,7 @@ class Numeric
|
|
50
50
|
|
51
51
|
def number?; true; end
|
52
52
|
|
53
|
-
end
|
53
|
+
end
|
54
54
|
|
55
55
|
|
56
56
|
class Integer
|
@@ -98,7 +98,7 @@ end
|
|
98
98
|
|
99
99
|
|
100
100
|
class String
|
101
|
-
|
101
|
+
|
102
102
|
#
|
103
103
|
# Could this string be cast to an integer?
|
104
104
|
#
|
data/lib/epitools/daemonize.rb
CHANGED
data/lib/epitools/hexdump.rb
CHANGED
data/lib/epitools/iter.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
# A stable iterator class.
|
3
3
|
# (You can reorder/remove elements in the container without affecting iteration.)
|
4
4
|
#
|
5
|
-
# For example, to reverse all the elements in a list:
|
5
|
+
# For example, to reverse all the elements in a list:
|
6
6
|
# >> i = Iter.new(1..10)
|
7
7
|
# >> i.each_cons(2) { |a,b| b.move_before(a) }
|
8
|
-
# >> i.to_a #=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
|
8
|
+
# >> i.to_a #=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
|
9
9
|
#
|
10
10
|
class Iter
|
11
11
|
|
@@ -15,7 +15,7 @@ class Iter
|
|
15
15
|
def initialize(vals)
|
16
16
|
@container = vals.map { |val| elem(val) }
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
# Wrap a value in an Elem container
|
20
20
|
def elem(val)
|
21
21
|
Elem.new(self, val)
|
@@ -33,21 +33,21 @@ class Iter
|
|
33
33
|
@container == other
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def each
|
38
38
|
@container.each do |elem|
|
39
39
|
yield elem
|
40
40
|
elem.visited = true
|
41
41
|
end
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
def each_cons(num=1)
|
45
45
|
@container.each_cons(num) do |(*elems)|
|
46
|
-
yield *elems
|
46
|
+
yield *elems
|
47
47
|
elems.each { |e| e.visited = true }
|
48
48
|
end
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
alias_method :iterate, :each_cons
|
52
52
|
alias_method :every, :each_cons
|
53
53
|
|
@@ -64,11 +64,11 @@ class Iter
|
|
64
64
|
result
|
65
65
|
end
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
|
69
69
|
|
70
70
|
class Elem < BasicObject
|
71
|
-
|
71
|
+
|
72
72
|
attr_accessor :val, :visited
|
73
73
|
|
74
74
|
def initialize(iter, val)
|
@@ -76,23 +76,23 @@ class Iter
|
|
76
76
|
@val = val.is_a?(Elem) ? val.value : val
|
77
77
|
@visited = false
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
def elem?
|
81
81
|
true
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
def container
|
85
85
|
@iter.container
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
def current
|
89
89
|
self
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
def visited?
|
93
93
|
@visited
|
94
94
|
end
|
95
|
-
|
95
|
+
|
96
96
|
def next
|
97
97
|
p = pos+1
|
98
98
|
if p >= container.size
|
@@ -101,7 +101,7 @@ class Iter
|
|
101
101
|
container[p]
|
102
102
|
end
|
103
103
|
end
|
104
|
-
|
104
|
+
|
105
105
|
def prev
|
106
106
|
p = pos-1
|
107
107
|
if p < 0
|
@@ -110,50 +110,50 @@ class Iter
|
|
110
110
|
container[p]
|
111
111
|
end
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
114
|
def remove
|
115
115
|
container.delete_at(pos)
|
116
116
|
end
|
117
117
|
alias_method :delete, :remove
|
118
|
-
|
118
|
+
|
119
119
|
def replace_with(replacement)
|
120
120
|
container[pos] = Elem.new(@iter, replacement)
|
121
121
|
end
|
122
|
-
|
122
|
+
|
123
123
|
def pos
|
124
124
|
container.index(self)
|
125
125
|
end
|
126
|
-
|
126
|
+
|
127
127
|
def move_before(other)
|
128
128
|
remove
|
129
129
|
container.insert(other.pos, self) # insert at pos and shift everything over
|
130
130
|
end
|
131
|
-
|
131
|
+
|
132
132
|
def move_after(other)
|
133
133
|
remove
|
134
134
|
container.insert(other.pos+1, self) # insert after pos
|
135
135
|
end
|
136
|
-
|
136
|
+
|
137
137
|
def move_first
|
138
138
|
remove
|
139
139
|
container.insert(0, self) # insert at beginning
|
140
140
|
end
|
141
141
|
alias_method :move_start, :move_first
|
142
|
-
|
142
|
+
|
143
143
|
def move_last
|
144
144
|
remove
|
145
145
|
container.insert(-1, self) # insert at end
|
146
146
|
end
|
147
147
|
alias_method :move_end, :move_last
|
148
|
-
|
148
|
+
|
149
149
|
def value
|
150
150
|
@val
|
151
151
|
end
|
152
|
-
|
152
|
+
|
153
153
|
def method_missing(name, *args)
|
154
154
|
@val.send(name, *args)
|
155
155
|
end
|
156
|
-
|
156
|
+
|
157
157
|
def inspect
|
158
158
|
"<Elem: #{@val.inspect}>"
|
159
159
|
end
|
@@ -172,5 +172,5 @@ class Iter
|
|
172
172
|
|
173
173
|
end
|
174
174
|
|
175
|
-
|
175
|
+
|
176
176
|
end
|
data/lib/epitools/lcs.rb
CHANGED
@@ -14,10 +14,10 @@ end
|
|
14
14
|
|
15
15
|
|
16
16
|
def longest_common_subsequence(s1, s2)
|
17
|
-
|
17
|
+
|
18
18
|
num = Array.new(s1.size) { Array.new(s2.size) }
|
19
19
|
len, ans = 0
|
20
|
-
|
20
|
+
|
21
21
|
s1.chars.each_with_index do |l1, i|
|
22
22
|
s2.chars.each_with_index do |l2, j|
|
23
23
|
unless l1==l2
|
@@ -34,6 +34,6 @@ def longest_common_subsequence(s1, s2)
|
|
34
34
|
end
|
35
35
|
|
36
36
|
ans
|
37
|
-
|
37
|
+
|
38
38
|
end
|
39
39
|
|
data/lib/epitools/mimemagic.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
#
|
2
2
|
# MimeMagic is a library to detect the mime type of a file by extension or by content.
|
3
|
-
#
|
3
|
+
#
|
4
4
|
# Usage
|
5
5
|
# =====
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# require 'mimemagic'
|
8
8
|
# MimeMagic.by_extension('html').text?
|
9
9
|
# MimeMagic.by_extension('.html').child_of? 'text/plain'
|
10
10
|
# MimeMagic.by_path('filename.txt')
|
11
11
|
# MimeMagic.by_magic(File.open('test.html'))
|
12
12
|
# etc...
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# Authors
|
15
15
|
# =======
|
16
16
|
# Daniel Mendler
|
@@ -73,7 +73,7 @@ class MimeMagic
|
|
73
73
|
def extensions
|
74
74
|
TYPES.key?(type) ? TYPES[type][0] : []
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
# Default extension
|
78
78
|
def ext
|
79
79
|
extensions.first
|
@@ -116,12 +116,12 @@ class MimeMagic
|
|
116
116
|
type == x.to_s
|
117
117
|
end
|
118
118
|
|
119
|
-
# allow comparison with hashes
|
119
|
+
# allow comparison with hashes
|
120
120
|
def hash
|
121
121
|
type.hash
|
122
122
|
end
|
123
|
-
|
124
|
-
# allow comparison with something else
|
123
|
+
|
124
|
+
# allow comparison with something else
|
125
125
|
def eql?(other)
|
126
126
|
self.type == other.type
|
127
127
|
end
|