webget_ruby_ramp 1.7.2
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.
- data.tar.gz.sig +0 -0
- data/lib/webget_ruby_ramp.rb +250 -0
- data/lib/webget_ruby_ramp/active_record.rb +119 -0
- data/lib/webget_ruby_ramp/active_record/connection_adapters/abstract/schema_statements.rb +24 -0
- data/lib/webget_ruby_ramp/active_record/save_extensions.rb +35 -0
- data/lib/webget_ruby_ramp/array.rb +370 -0
- data/lib/webget_ruby_ramp/csv.rb +53 -0
- data/lib/webget_ruby_ramp/date.rb +90 -0
- data/lib/webget_ruby_ramp/enumerable.rb +385 -0
- data/lib/webget_ruby_ramp/file.rb +15 -0
- data/lib/webget_ruby_ramp/hash.rb +223 -0
- data/lib/webget_ruby_ramp/integer.rb +22 -0
- data/lib/webget_ruby_ramp/io.rb +65 -0
- data/lib/webget_ruby_ramp/kernel.rb +36 -0
- data/lib/webget_ruby_ramp/math.rb +20 -0
- data/lib/webget_ruby_ramp/nil.rb +17 -0
- data/lib/webget_ruby_ramp/numeric.rb +98 -0
- data/lib/webget_ruby_ramp/object.rb +20 -0
- data/lib/webget_ruby_ramp/process.rb +153 -0
- data/lib/webget_ruby_ramp/string.rb +221 -0
- data/lib/webget_ruby_ramp/symbol.rb +11 -0
- data/lib/webget_ruby_ramp/time.rb +11 -0
- data/lib/webget_ruby_ramp/xml.rb +193 -0
- data/lib/webget_ruby_ramp/yaml.rb +34 -0
- data/test/webget_ruby_ramp/active_record/connection_adapters/abstract/schema_statements_test.rb +9 -0
- data/test/webget_ruby_ramp/active_record/save_extensions_test.rb +7 -0
- data/test/webget_ruby_ramp/active_record_test.rb +64 -0
- data/test/webget_ruby_ramp/array_test.rb +171 -0
- data/test/webget_ruby_ramp/csv_test.rb +18 -0
- data/test/webget_ruby_ramp/date_test.rb +60 -0
- data/test/webget_ruby_ramp/enumerable_test.rb +275 -0
- data/test/webget_ruby_ramp/file_test.rb +15 -0
- data/test/webget_ruby_ramp/hash_test.rb +105 -0
- data/test/webget_ruby_ramp/integer_test.rb +19 -0
- data/test/webget_ruby_ramp/io_test.rb +31 -0
- data/test/webget_ruby_ramp/io_test.txt +1 -0
- data/test/webget_ruby_ramp/kernel_test.rb +15 -0
- data/test/webget_ruby_ramp/math_test.rb +17 -0
- data/test/webget_ruby_ramp/nil_test.rb +15 -0
- data/test/webget_ruby_ramp/numeric_test.rb +28 -0
- data/test/webget_ruby_ramp/object_test.rb +12 -0
- data/test/webget_ruby_ramp/process_test.rb +24 -0
- data/test/webget_ruby_ramp/string_test.rb +125 -0
- data/test/webget_ruby_ramp/symbol_test.rb +26 -0
- data/test/webget_ruby_ramp/time_test.rb +12 -0
- data/test/webget_ruby_ramp/xml_test.rb +93 -0
- data/test/webget_ruby_ramp/xml_test_1.xml +5 -0
- data/test/webget_ruby_ramp/xml_test_2.xml +5 -0
- data/test/webget_ruby_ramp/xml_test_msword_clean.html +1 -0
- data/test/webget_ruby_ramp/xml_test_msword_dirty.html +148 -0
- data/test/webget_ruby_ramp/yaml_test.rb +32 -0
- data/test/webget_ruby_ramp/yaml_test_1.yml +38 -0
- data/test/webget_ruby_ramp/yaml_test_2.yml +38 -0
- metadata +128 -0
- metadata.gz.sig +1 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
# File extensions
|
2
|
+
|
3
|
+
class File
|
4
|
+
|
5
|
+
# Return File.join(File.dirname(dirname),strings)
|
6
|
+
#
|
7
|
+
# ==Example
|
8
|
+
# File.joindir(__FILE__,'foo.txt')
|
9
|
+
# => '/home/john/foo.txt'
|
10
|
+
|
11
|
+
def File.joindir(dirname,*strings)
|
12
|
+
File.join(File.dirname(dirname),strings)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
# Hash extensions
|
4
|
+
|
5
|
+
class Hash
|
6
|
+
|
7
|
+
|
8
|
+
# Return true if size > 0
|
9
|
+
def size?
|
10
|
+
size>0
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
# Calls block once for each key in hsh, passing the key and value to the block as a two-element array.
|
15
|
+
#
|
16
|
+
# The keys are sorted.
|
17
|
+
|
18
|
+
def each_sort
|
19
|
+
keys.sort.each{|key| yield key,self[key] }
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
# Calls block once for each key in hsh,
|
24
|
+
# passing the key as a parameter,
|
25
|
+
# and updating it in place.
|
26
|
+
#
|
27
|
+
# ==Example
|
28
|
+
# h = { "a" => "b", "c" => "d" }
|
29
|
+
# h.each_key! {|key| key.upcase }
|
30
|
+
# h => { "A" => "b", "C" => "d" }
|
31
|
+
#
|
32
|
+
# Return self.
|
33
|
+
|
34
|
+
def each_key!
|
35
|
+
each_pair{|key,value|
|
36
|
+
key2=yield(key)
|
37
|
+
if key===key2
|
38
|
+
#nop
|
39
|
+
else
|
40
|
+
self.delete(key)
|
41
|
+
self[key2]=value
|
42
|
+
end
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# Calls block once for each key in hsh,
|
48
|
+
# passing the key and value as parameters,
|
49
|
+
# and updated them in place.
|
50
|
+
#
|
51
|
+
# ==Example
|
52
|
+
# h = { "a" => "b", "c" => "d" }
|
53
|
+
# h.each_pair! {|key,value| key.upcase, value.upcase }
|
54
|
+
# h => { "A" => "B", "C" => "D" }
|
55
|
+
#
|
56
|
+
# Return self.
|
57
|
+
|
58
|
+
def each_pair!
|
59
|
+
each_pair{|key,value|
|
60
|
+
key2,value2=yield(key,value)
|
61
|
+
if key===key2
|
62
|
+
if value===value2
|
63
|
+
#nop
|
64
|
+
else
|
65
|
+
self[key]=value2
|
66
|
+
end
|
67
|
+
else
|
68
|
+
self.delete(key)
|
69
|
+
self[key2]=value2
|
70
|
+
end
|
71
|
+
}
|
72
|
+
return self
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# Calls block once for each key in hsh,
|
77
|
+
# passing the value as a parameter,
|
78
|
+
# and updating it in place.
|
79
|
+
#
|
80
|
+
# ==Example
|
81
|
+
# h = { "a" => "b", "c" => "d" }
|
82
|
+
# h.each_value! {|value| value.upcase }
|
83
|
+
# h => { "a" => "B", "c" => "d" }
|
84
|
+
#
|
85
|
+
# Return self.
|
86
|
+
|
87
|
+
def each_value!
|
88
|
+
each_pair{|key,value|
|
89
|
+
value2=yield(value)
|
90
|
+
if value===value2
|
91
|
+
#nop
|
92
|
+
else
|
93
|
+
self[key]=yield(value)
|
94
|
+
end
|
95
|
+
}
|
96
|
+
return self
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
# Calls block once for each key-value pair in hsh,
|
101
|
+
# passing the key and value as paramters to the block.
|
102
|
+
#
|
103
|
+
# ==Example
|
104
|
+
# h = {"a"=>"b", "c"=>"d", "e"=>"f" }
|
105
|
+
# h.map_pair{|key,value| key+value }
|
106
|
+
# => ["ab","cd","ef"]
|
107
|
+
|
108
|
+
def map_pair
|
109
|
+
keys.map{|key| yield key, self[key] }
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# Hash#to_yaml with sort
|
114
|
+
#
|
115
|
+
# From http://snippets.dzone.com/tag/yaml
|
116
|
+
|
117
|
+
def to_yaml_sort( opts = {} )
|
118
|
+
YAML::quick_emit( object_id, opts ) do |out|
|
119
|
+
out.map( taguri, to_yaml_style ) do |map|
|
120
|
+
sort.each do |key, val| # <-- here's my addition (the 'sort')
|
121
|
+
map.add(key, val)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
# Hash#pivot aggregates values for a hash of hashes,
|
129
|
+
# for example to calculate subtotals and groups.
|
130
|
+
#
|
131
|
+
# Suppose you have data arranged by companies, roles, and headcounts.
|
132
|
+
#
|
133
|
+
# data = {
|
134
|
+
# "Apple" => {"Accountants" => 11, "Designers" => 22, "Developers" => 33},
|
135
|
+
# "Goggle" => {"Accountants" => 44, "Designers" => 55, "Developers" => 66},
|
136
|
+
# "Microsoft" => {"Accountants" => 77, "Designers" => 88, "Developers" => 99},
|
137
|
+
# }
|
138
|
+
#
|
139
|
+
# To calculate each company's total headcount, you pivot up, then sum:
|
140
|
+
#
|
141
|
+
# data.pivot(:up,&:sum)
|
142
|
+
# => {
|
143
|
+
# "Apple"=>66,
|
144
|
+
# "Goggle"=>165,
|
145
|
+
# "Microsoft"=>264
|
146
|
+
# }
|
147
|
+
#
|
148
|
+
# To calculate each role's total headcount, you pivot down, then sum:
|
149
|
+
#
|
150
|
+
# data.pivot(:down,&:sum)
|
151
|
+
# => {
|
152
|
+
# "Accountants"=>132,
|
153
|
+
# "Designers"=>165,
|
154
|
+
# "Developers"=>198
|
155
|
+
# }
|
156
|
+
#
|
157
|
+
# Generic xxample:
|
158
|
+
# h={
|
159
|
+
# "a"=>{"x"=>1,"y"=>2,"z"=>3},
|
160
|
+
# "b"=>{"x"=>4,"y"=>5,"z"=>6},
|
161
|
+
# "c"=>{"x"=>7,"y"=>8,"z"=>9},
|
162
|
+
# }
|
163
|
+
# h.pivot(:keys) => {"a"=>[1,2,3],"b"=>[4,5,6],"c"=>[7,8,9]}
|
164
|
+
# h.pivot(:vals) => {"x"=>[1,4,7],"y"=>[2,5,8],"z"=>[3,6,9]}
|
165
|
+
#
|
166
|
+
# = Calculating subtotals
|
167
|
+
#
|
168
|
+
# The pivot method is especially useful for calculating subtotals.
|
169
|
+
#
|
170
|
+
# ==Example
|
171
|
+
# r = h.pivot(:keys)
|
172
|
+
# r['a'].sum => 6
|
173
|
+
# r['b'].sum => 15
|
174
|
+
# r['c'].sum => 24
|
175
|
+
#
|
176
|
+
# ==Example
|
177
|
+
# r=h.pivot(:vals)
|
178
|
+
# r['x'].sum => 12
|
179
|
+
# r['y'].sum => 15
|
180
|
+
# r['z'].sum => 18
|
181
|
+
#
|
182
|
+
# = Block customization
|
183
|
+
#
|
184
|
+
# You can provide a block that will be called for the pivot items.
|
185
|
+
#
|
186
|
+
# ==Examples
|
187
|
+
# h.pivot(:keys){|items| items.max } => {"a"=>3,"b"=>6,"c"=>9}
|
188
|
+
# h.pivot(:keys){|items| items.join("/") } => {"a"=>"1/2/3","b"=>"4/5/6","c"=>"7/8/9"}
|
189
|
+
# h.pivot(:keys){|items| items.inject{|sum,x| sum+=x } } => {"a"=>6,"b"=>15,"c"=>24}
|
190
|
+
#
|
191
|
+
# ==Examples
|
192
|
+
# h.pivot(:vals){|items| items.max } => {"a"=>7,"b"=>8,"c"=>9}
|
193
|
+
# h.pivot(:vals){|items| items.join("-") } => {"a"=>"1-4-7","b"=>"2-5-8","c"=>"3-6-9"}
|
194
|
+
# h.pivot(:vals){|items| items.inject{|sum,x| sum+=x } } => {"a"=>12,"b"=>15,"c"=>18}
|
195
|
+
|
196
|
+
def pivot(direction='keys',&b)
|
197
|
+
a=self.class.new
|
198
|
+
direction=direction.to_s
|
199
|
+
up=pivot_direction_up?(direction)
|
200
|
+
each_pair{|k1,v1|
|
201
|
+
v1.each_pair{|k2,v2|
|
202
|
+
k = up ? k1 : k2
|
203
|
+
a[k]=[] if (a[k]==nil or a[k]=={})
|
204
|
+
a[k]<<(v2)
|
205
|
+
}
|
206
|
+
}
|
207
|
+
if block_given?
|
208
|
+
a.each_pair{|k,v| a[k]=(yield v)}
|
209
|
+
end
|
210
|
+
a
|
211
|
+
end
|
212
|
+
|
213
|
+
protected
|
214
|
+
|
215
|
+
def pivot_direction_up?(direction_name)
|
216
|
+
case direction_name
|
217
|
+
when 'key','keys','up','left','out' then return true
|
218
|
+
when 'val','vals','down','right','in' then return false
|
219
|
+
else raise 'Pivot direction must be either: up/left/out or down/right/in'
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Integer extensions
|
2
|
+
|
3
|
+
class Integer
|
4
|
+
|
5
|
+
# Syntactic sugar to yield n times to a block.
|
6
|
+
#
|
7
|
+
# Return an array of any results.
|
8
|
+
#
|
9
|
+
# ==Example
|
10
|
+
# 3.maps{rand} => [0.0248131784304143, 0.814666170190905, 0.15812816258206]
|
11
|
+
#
|
12
|
+
# ==Parallel to Integer#times
|
13
|
+
#
|
14
|
+
# Integer#maps is similar to Integer#times except that the output from each
|
15
|
+
# call to the block is captured in an array element and that array is
|
16
|
+
# returned to the calling code.
|
17
|
+
|
18
|
+
def maps
|
19
|
+
(0...self).map{|item| yield item}
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# IO extensions
|
2
|
+
|
3
|
+
class IO
|
4
|
+
|
5
|
+
|
6
|
+
# Reads the entire file specified by name as individual lines as with IO#readlines,
|
7
|
+
# and returns those lines in an array of rows, where each row is an array of fields.
|
8
|
+
#
|
9
|
+
# ==Example
|
10
|
+
# IO.readrows("my.tsv")
|
11
|
+
# => [["A1","B1","C1"],["A2","B2","C2"],["A3","B3","C3"]]
|
12
|
+
#
|
13
|
+
# ==Options
|
14
|
+
# - Rows are separated by _row_ option, which defaults to Ruby's record separator $/ or "\n"
|
15
|
+
# - Cols are separated by _col_ option, which defaults to Ruby's string split separator $; or "\t"
|
16
|
+
#
|
17
|
+
# ==Example with options suitable for a file using TSV (Tab Separated Values)
|
18
|
+
# IO.readrows("my.tsv", :row=>"\n", :col=>"\t")
|
19
|
+
#
|
20
|
+
# Note: the col option is sent along to String#split, so can be a string or a regexp.
|
21
|
+
#
|
22
|
+
# See:
|
23
|
+
# - File#readline
|
24
|
+
# - File#readlines
|
25
|
+
# - File#readrow
|
26
|
+
|
27
|
+
def IO.readrows(name, options={})
|
28
|
+
row_sep||=options[:row]||$/||"\n"
|
29
|
+
col_sep||=options[:col]||$;||"\t"
|
30
|
+
return IO.readlines(name, row_sep).map{|line| line.chomp(row_sep).split(col_sep)}
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# Read a line as with IO#readline and return the line as a row of fields.
|
35
|
+
#
|
36
|
+
# ==Example
|
37
|
+
# file = File.new("my.tsv")
|
38
|
+
# file.readrow() => ["A1","B1","C1"]
|
39
|
+
# file.readrow() => ["A2","B2","C2"]
|
40
|
+
# file.readrow() => ["A3","B3","C3"]]
|
41
|
+
#
|
42
|
+
# ==Options
|
43
|
+
# - Rows are separated by _row_ option, which defaults to Ruby's record separator $/ or "\n"
|
44
|
+
# - Cols are separated by _col_ option, which defaults to Ruby's string split separator $; or "\t"
|
45
|
+
#
|
46
|
+
# ==Example with options suitable for a file using TSV (Tab Separated Values)
|
47
|
+
# file = File.new("my.tsv")
|
48
|
+
# file.readrow(:row=>"\n", :col=>"\t") => ["A1","B1","C1"]
|
49
|
+
# file.readrow(:row=>"\n", :col=>"\t") => ["A2","B2","C2"]
|
50
|
+
# file.readrow(:row=>"\n", :col=>"\t") => ["A3","B3","C3"]
|
51
|
+
#
|
52
|
+
# Note: the col option is sent along to String#split, so can be a string or a regexp.
|
53
|
+
#
|
54
|
+
# See:
|
55
|
+
# - File#readline
|
56
|
+
# - File#readlines
|
57
|
+
# - File#readrows
|
58
|
+
|
59
|
+
def readrow(options={})
|
60
|
+
row_sep||=options[:row]||$/||"\n"
|
61
|
+
col_sep||=options[:col]||$;||"\t"
|
62
|
+
return readline(row_sep).chomp(row_sep).split(col_sep)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
# Kernel extensions
|
5
|
+
|
6
|
+
module Kernel
|
7
|
+
|
8
|
+
# See:
|
9
|
+
# - http://www.ruby-forum.com/topic/75258
|
10
|
+
# - In 1.9 (Ruby CVS HEAD) there is #__method__ and #__callee__
|
11
|
+
# - http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l90
|
12
|
+
|
13
|
+
def method_name(caller_index=0)
|
14
|
+
# Make this fast because its often doing logging & reporting.
|
15
|
+
# Inline this and use $1 because it's empirically faster than /1
|
16
|
+
caller[caller_index] =~ /`([^']*)'/ and $1
|
17
|
+
end
|
18
|
+
|
19
|
+
# Pretty print to a string.
|
20
|
+
#
|
21
|
+
# Created by Graeme Mathieson.
|
22
|
+
#
|
23
|
+
# See http://rha7dotcom.blogspot.com/2008/07/ruby-and-rails-how-to-get-pp-pretty.html
|
24
|
+
|
25
|
+
def pp_s(*objs)
|
26
|
+
str = StringIO.new
|
27
|
+
objs.each {|obj|
|
28
|
+
PP.pp(obj, str)
|
29
|
+
}
|
30
|
+
str.rewind
|
31
|
+
str.read
|
32
|
+
end
|
33
|
+
module_function :pp_s
|
34
|
+
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Math extensions
|
2
|
+
|
3
|
+
module Math
|
4
|
+
|
5
|
+
|
6
|
+
# Return the natural log of _num_
|
7
|
+
|
8
|
+
def Math.ln(num)
|
9
|
+
Math.log(num)
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
# Return the log of _num_ in base _base_
|
14
|
+
|
15
|
+
def Math.logn(num,base)
|
16
|
+
Math.ln(num)/Math.ln(base)
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# Numeric extensions
|
2
|
+
|
3
|
+
class Numeric
|
4
|
+
|
5
|
+
|
6
|
+
# Return 0 if the given flag is any of: nil, false, 0, [], {}
|
7
|
+
#
|
8
|
+
# ==Example
|
9
|
+
# 3.if(true) => 3
|
10
|
+
# 3.if(false) => 0
|
11
|
+
#
|
12
|
+
|
13
|
+
def if(flag)
|
14
|
+
# inline for speed
|
15
|
+
return (flag==nil or flag==false or flag==0 or flag==[] or flag=={}) ? 0 : self
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
# Return self if flag is nil, false, 0, [], {}; otherwise return 0.
|
20
|
+
#
|
21
|
+
# ==Example
|
22
|
+
# 3.unless(true) => 0
|
23
|
+
# 3.unless(false) => 3
|
24
|
+
|
25
|
+
def unless(flag)
|
26
|
+
# inline for speed
|
27
|
+
return (flag==nil or flag==false or flag==0 or flag==[] or flag=={}) ? self : 0
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
###
|
32
|
+
#
|
33
|
+
# Metric conversions
|
34
|
+
#
|
35
|
+
###
|
36
|
+
|
37
|
+
# Return self / 10^15
|
38
|
+
def peta
|
39
|
+
self/1000000000000000
|
40
|
+
end
|
41
|
+
|
42
|
+
# Return self / 10^12
|
43
|
+
def tera
|
44
|
+
self/1000000000000
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return self / 10^9
|
48
|
+
def giga
|
49
|
+
self/1000000000
|
50
|
+
end
|
51
|
+
|
52
|
+
# Return self / 10^6
|
53
|
+
def mega
|
54
|
+
self/100000
|
55
|
+
end
|
56
|
+
|
57
|
+
# Return self / 10^3
|
58
|
+
def kilo
|
59
|
+
self/1000
|
60
|
+
end
|
61
|
+
|
62
|
+
# Return self / 10^2
|
63
|
+
def hecto
|
64
|
+
self/100
|
65
|
+
end
|
66
|
+
|
67
|
+
# Return self / 10
|
68
|
+
def deka
|
69
|
+
self/10
|
70
|
+
end
|
71
|
+
|
72
|
+
# Return self * 10
|
73
|
+
def deci
|
74
|
+
self*10
|
75
|
+
end
|
76
|
+
|
77
|
+
# Return self * 10^2
|
78
|
+
def centi
|
79
|
+
self*100
|
80
|
+
end
|
81
|
+
|
82
|
+
# Return self * 10^3
|
83
|
+
def milli
|
84
|
+
self*1000
|
85
|
+
end
|
86
|
+
|
87
|
+
# Return self * 10^6
|
88
|
+
def micro
|
89
|
+
self*1000000
|
90
|
+
end
|
91
|
+
|
92
|
+
# Return self * 10^9
|
93
|
+
def nano
|
94
|
+
self*1000000000
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
end
|