forkoff 0.0.0
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/README +146 -0
- data/gemspec.rb +35 -0
- data/gen_readme.rb +32 -0
- data/install.rb +214 -0
- data/lib/forkoff.rb +92 -0
- data/samples/a.rb +8 -0
- data/samples/b.rb +23 -0
- data/samples/c.rb +33 -0
- metadata +62 -0
data/README
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
NAME
|
2
|
+
|
3
|
+
forkoff
|
4
|
+
|
5
|
+
SYNOPSIS
|
6
|
+
|
7
|
+
brain-dead simple parallel processing for ruby
|
8
|
+
|
9
|
+
URI
|
10
|
+
|
11
|
+
http://rubyforge.org/projects/codeforpeople
|
12
|
+
|
13
|
+
INSTALL
|
14
|
+
|
15
|
+
gem install forkoff
|
16
|
+
|
17
|
+
DESCRIPTION
|
18
|
+
|
19
|
+
forkoff works for any enumerable object, iterating a code block to run in a
|
20
|
+
child process and collecting the results. forkoff can limit the number of
|
21
|
+
child processes which is, by default, 8.
|
22
|
+
|
23
|
+
SAMPLES
|
24
|
+
|
25
|
+
<========< samples/a.rb >========>
|
26
|
+
|
27
|
+
~ > cat samples/a.rb
|
28
|
+
|
29
|
+
#
|
30
|
+
# forkoff makes it trivial to do parallel processing with ruby, the following
|
31
|
+
# prints out each word in a separate process
|
32
|
+
#
|
33
|
+
|
34
|
+
require 'forkoff'
|
35
|
+
|
36
|
+
%w( hey you ).forkoff!{|word| puts "#{ word } from #{ Process.pid }"}
|
37
|
+
|
38
|
+
~ > ruby samples/a.rb
|
39
|
+
|
40
|
+
hey from 3239
|
41
|
+
you from 3240
|
42
|
+
|
43
|
+
|
44
|
+
<========< samples/b.rb >========>
|
45
|
+
|
46
|
+
~ > cat samples/b.rb
|
47
|
+
|
48
|
+
#
|
49
|
+
# for example, this takes only 1 second or so to complete
|
50
|
+
#
|
51
|
+
|
52
|
+
require 'forkoff'
|
53
|
+
|
54
|
+
a = Time.now.to_f
|
55
|
+
|
56
|
+
results =
|
57
|
+
(0..7).forkoff do |i|
|
58
|
+
|
59
|
+
sleep 1
|
60
|
+
|
61
|
+
i ** 2
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
b = Time.now.to_f
|
66
|
+
|
67
|
+
elapsed = b - a
|
68
|
+
|
69
|
+
puts "elapsed: #{ elapsed }"
|
70
|
+
puts "results: #{ results.inspect }"
|
71
|
+
|
72
|
+
~ > ruby samples/b.rb
|
73
|
+
|
74
|
+
elapsed: 1.07044386863708
|
75
|
+
results: [0, 1, 4, 9, 16, 25, 36, 49]
|
76
|
+
|
77
|
+
|
78
|
+
<========< samples/c.rb >========>
|
79
|
+
|
80
|
+
~ > cat samples/c.rb
|
81
|
+
|
82
|
+
#
|
83
|
+
# forkoff does *NOT* spawn processes in batches, waiting for each batch to
|
84
|
+
# complete. rather, it keeps a certain number of processes busy until all
|
85
|
+
# results have been gathered. in otherwords the following will ensure that 2
|
86
|
+
# processes are running at all times, until the list is complete. note that
|
87
|
+
# the following will take about 2 seconds to run (2 sets of 2 @ 1 second).
|
88
|
+
#
|
89
|
+
|
90
|
+
require 'forkoff'
|
91
|
+
|
92
|
+
pid = Process.pid
|
93
|
+
|
94
|
+
a = Time.now.to_f
|
95
|
+
|
96
|
+
pstrees =
|
97
|
+
%w( a b c d ).forkoff! :processes => 2 do |letter|
|
98
|
+
sleep 1
|
99
|
+
{ letter => ` pstree -l 2 #{ pid } ` }
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
b = Time.now.to_f
|
104
|
+
|
105
|
+
puts
|
106
|
+
puts "pid: #{ pid }"
|
107
|
+
puts "elapsed: #{ b - a }"
|
108
|
+
puts
|
109
|
+
|
110
|
+
require 'yaml'
|
111
|
+
|
112
|
+
pstrees.each do |pstree|
|
113
|
+
y pstree
|
114
|
+
end
|
115
|
+
|
116
|
+
~ > ruby samples/c.rb
|
117
|
+
|
118
|
+
|
119
|
+
pid: 3254
|
120
|
+
elapsed: 2.12998485565186
|
121
|
+
|
122
|
+
---
|
123
|
+
a: |
|
124
|
+
-+- 03254 ahoward ruby -Ilib samples/c.rb
|
125
|
+
|-+- 03255 ahoward ruby -Ilib samples/c.rb
|
126
|
+
\-+- 03256 ahoward ruby -Ilib samples/c.rb
|
127
|
+
|
128
|
+
---
|
129
|
+
b: |
|
130
|
+
-+- 03254 ahoward ruby -Ilib samples/c.rb
|
131
|
+
|-+- 03255 ahoward ruby -Ilib samples/c.rb
|
132
|
+
\-+- 03256 ahoward ruby -Ilib samples/c.rb
|
133
|
+
|
134
|
+
---
|
135
|
+
c: |
|
136
|
+
-+- 03254 ahoward ruby -Ilib samples/c.rb
|
137
|
+
|-+- 03261 ahoward (ruby)
|
138
|
+
\-+- 03262 ahoward ruby -Ilib samples/c.rb
|
139
|
+
|
140
|
+
---
|
141
|
+
d: |
|
142
|
+
-+- 03254 ahoward ruby -Ilib samples/c.rb
|
143
|
+
|-+- 03261 ahoward ruby -Ilib samples/c.rb
|
144
|
+
\-+- 03262 ahoward ruby -Ilib samples/c.rb
|
145
|
+
|
146
|
+
|
data/gemspec.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
Gem::Specification::new do |spec|
|
6
|
+
$VERBOSE = nil
|
7
|
+
|
8
|
+
shiteless = lambda do |list|
|
9
|
+
list.delete_if do |file|
|
10
|
+
file =~ %r/\.svn/ or
|
11
|
+
file =~ %r/\.tmp/
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
spec.name = lib
|
16
|
+
spec.version = version
|
17
|
+
spec.platform = Gem::Platform::RUBY
|
18
|
+
spec.summary = lib
|
19
|
+
|
20
|
+
spec.files = shiteless[Dir::glob("**/**")]
|
21
|
+
spec.executables = shiteless[Dir::glob("bin/*")].map{|exe| File::basename exe}
|
22
|
+
|
23
|
+
spec.require_path = "lib"
|
24
|
+
spec.autorequire = lib
|
25
|
+
|
26
|
+
spec.has_rdoc = File::exist? "doc"
|
27
|
+
spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
|
28
|
+
#spec.add_dependency 'lib', '>= version'
|
29
|
+
|
30
|
+
spec.extensions << "extconf.rb" if File::exists? "extconf.rb"
|
31
|
+
|
32
|
+
spec.author = "Ara T. Howard"
|
33
|
+
spec.email = "ara.t.howard@gmail.com"
|
34
|
+
spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
|
35
|
+
end
|
data/gen_readme.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
$VERBOSE=nil
|
4
|
+
|
5
|
+
def indent s, n = 2
|
6
|
+
ws = ' ' * n
|
7
|
+
s.gsub %r/^/, ws
|
8
|
+
end
|
9
|
+
|
10
|
+
template = IO::read 'README.tmpl'
|
11
|
+
|
12
|
+
samples = ''
|
13
|
+
prompt = '~ > '
|
14
|
+
|
15
|
+
Dir['sample*/*'].sort.each do |sample|
|
16
|
+
samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
|
17
|
+
|
18
|
+
cmd = "cat #{ sample }"
|
19
|
+
samples << indent(prompt + cmd, 2) << "\n\n"
|
20
|
+
samples << indent(`#{ cmd }`, 4) << "\n"
|
21
|
+
|
22
|
+
cmd = "ruby #{ sample }"
|
23
|
+
samples << indent(prompt + cmd, 2) << "\n\n"
|
24
|
+
|
25
|
+
cmd = "ruby -Ilib #{ sample }"
|
26
|
+
samples << indent(`#{ cmd } 2>&1`, 4) << "\n"
|
27
|
+
end
|
28
|
+
|
29
|
+
#samples.gsub! %r/^/, ' '
|
30
|
+
|
31
|
+
readme = template.gsub %r/^\s*@samples\s*$/, samples
|
32
|
+
print readme
|
data/install.rb
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rbconfig'
|
3
|
+
require 'find'
|
4
|
+
require 'ftools'
|
5
|
+
require 'tempfile'
|
6
|
+
include Config
|
7
|
+
|
8
|
+
LIBDIR = "lib"
|
9
|
+
LIBDIR_MODE = 0644
|
10
|
+
|
11
|
+
BINDIR = "bin"
|
12
|
+
BINDIR_MODE = 0755
|
13
|
+
|
14
|
+
|
15
|
+
$srcdir = CONFIG["srcdir"]
|
16
|
+
$version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
|
17
|
+
$libdir = File.join(CONFIG["libdir"], "ruby", $version)
|
18
|
+
$archdir = File.join($libdir, CONFIG["arch"])
|
19
|
+
$site_libdir = $:.find {|x| x =~ /site_ruby$/}
|
20
|
+
$bindir = CONFIG["bindir"] || CONFIG['BINDIR']
|
21
|
+
$ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
|
22
|
+
$ruby_ext = CONFIG['EXEEXT'] || ''
|
23
|
+
$ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
|
24
|
+
|
25
|
+
if !$site_libdir
|
26
|
+
$site_libdir = File.join($libdir, "site_ruby")
|
27
|
+
elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
|
28
|
+
$site_libdir = File.join($site_libdir, $version)
|
29
|
+
end
|
30
|
+
|
31
|
+
def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
|
32
|
+
#{{{
|
33
|
+
path = []
|
34
|
+
dir = []
|
35
|
+
Find.find(srcdir) do |f|
|
36
|
+
next unless FileTest.file?(f)
|
37
|
+
next if (f = f[srcdir.length+1..-1]) == nil
|
38
|
+
next if (/CVS$/ =~ File.dirname(f))
|
39
|
+
next if (/\.svn/ =~ File.dirname(f))
|
40
|
+
next if f =~ %r/\.lnk/
|
41
|
+
next if f =~ %r/\.svn/
|
42
|
+
next if f =~ %r/\.swp/
|
43
|
+
next if f =~ %r/\.svn/
|
44
|
+
path.push f
|
45
|
+
dir |= [File.dirname(f)]
|
46
|
+
end
|
47
|
+
for f in dir
|
48
|
+
next if f == "."
|
49
|
+
next if f == "CVS"
|
50
|
+
File::makedirs(File.join(destdir, f))
|
51
|
+
end
|
52
|
+
for f in path
|
53
|
+
next if (/\~$/ =~ f)
|
54
|
+
next if (/^\./ =~ File.basename(f))
|
55
|
+
unless bin
|
56
|
+
File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
|
57
|
+
else
|
58
|
+
from = File.join(srcdir, f)
|
59
|
+
to = File.join(destdir, f)
|
60
|
+
shebangify(from) do |sf|
|
61
|
+
$deferr.print from, " -> ", File::catname(from, to), "\n"
|
62
|
+
$deferr.printf "chmod %04o %s\n", mode, to
|
63
|
+
File::install(sf, to, mode, false)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
#}}}
|
68
|
+
end
|
69
|
+
def shebangify f
|
70
|
+
#{{{
|
71
|
+
open(f) do |fd|
|
72
|
+
buf = fd.read 42
|
73
|
+
if buf =~ %r/^\s*#\s*!.*ruby/o
|
74
|
+
ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
|
75
|
+
begin
|
76
|
+
fd.rewind
|
77
|
+
ftmp.puts "#!#{ $ruby }"
|
78
|
+
while((buf = fd.read(8192)))
|
79
|
+
ftmp.write buf
|
80
|
+
end
|
81
|
+
ftmp.close
|
82
|
+
yield ftmp.path
|
83
|
+
ensure
|
84
|
+
ftmp.close!
|
85
|
+
end
|
86
|
+
else
|
87
|
+
yield f
|
88
|
+
end
|
89
|
+
end
|
90
|
+
#}}}
|
91
|
+
end
|
92
|
+
def ARGV.switch
|
93
|
+
#{{{
|
94
|
+
return nil if self.empty?
|
95
|
+
arg = self.shift
|
96
|
+
return nil if arg == '--'
|
97
|
+
if arg =~ /^-(.)(.*)/
|
98
|
+
return arg if $1 == '-'
|
99
|
+
raise 'unknown switch "-"' if $2.index('-')
|
100
|
+
self.unshift "-#{$2}" if $2.size > 0
|
101
|
+
"-#{$1}"
|
102
|
+
else
|
103
|
+
self.unshift arg
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
#}}}
|
107
|
+
end
|
108
|
+
def ARGV.req_arg
|
109
|
+
#{{{
|
110
|
+
self.shift || raise('missing argument')
|
111
|
+
#}}}
|
112
|
+
end
|
113
|
+
def linkify d, linked = []
|
114
|
+
#--{{{
|
115
|
+
if test ?d, d
|
116
|
+
versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
|
117
|
+
versioned.each do |v|
|
118
|
+
src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
|
119
|
+
lnk = nil
|
120
|
+
begin
|
121
|
+
if test ?l, dst
|
122
|
+
lnk = "#{ dst }.lnk"
|
123
|
+
puts "#{ dst } -> #{ lnk }"
|
124
|
+
File::rename dst, lnk
|
125
|
+
end
|
126
|
+
unless test ?e, dst
|
127
|
+
puts "#{ src } -> #{ dst }"
|
128
|
+
File::copy src, dst
|
129
|
+
linked << dst
|
130
|
+
end
|
131
|
+
ensure
|
132
|
+
if lnk
|
133
|
+
at_exit do
|
134
|
+
puts "#{ lnk } -> #{ dst }"
|
135
|
+
File::rename lnk, dst
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
linked
|
142
|
+
#--}}}
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
#
|
147
|
+
# main program
|
148
|
+
#
|
149
|
+
|
150
|
+
libdir = $site_libdir
|
151
|
+
bindir = $bindir
|
152
|
+
no_linkify = false
|
153
|
+
linked = nil
|
154
|
+
help = false
|
155
|
+
|
156
|
+
usage = <<-usage
|
157
|
+
#{ File::basename $0 }
|
158
|
+
-d, --destdir <destdir>
|
159
|
+
-l, --libdir <libdir>
|
160
|
+
-b, --bindir <bindir>
|
161
|
+
-r, --ruby <ruby>
|
162
|
+
-n, --no_linkify
|
163
|
+
-s, --sudo
|
164
|
+
-h, --help
|
165
|
+
usage
|
166
|
+
|
167
|
+
begin
|
168
|
+
while switch = ARGV.switch
|
169
|
+
case switch
|
170
|
+
when '-d', '--destdir'
|
171
|
+
libdir = ARGV.req_arg
|
172
|
+
when '-l', '--libdir'
|
173
|
+
libdir = ARGV.req_arg
|
174
|
+
when '-b', '--bindir'
|
175
|
+
bindir = ARGV.req_arg
|
176
|
+
when '-r', '--ruby'
|
177
|
+
$ruby = ARGV.req_arg
|
178
|
+
when '-n', '--no_linkify'
|
179
|
+
no_linkify = true
|
180
|
+
when '-s', '--sudo'
|
181
|
+
sudo = 'sudo'
|
182
|
+
when '-h', '--help'
|
183
|
+
help = true
|
184
|
+
else
|
185
|
+
raise "unknown switch #{switch.dump}"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
rescue
|
189
|
+
STDERR.puts $!.to_s
|
190
|
+
STDERR.puts usage
|
191
|
+
exit 1
|
192
|
+
end
|
193
|
+
|
194
|
+
if help
|
195
|
+
STDOUT.puts usage
|
196
|
+
exit
|
197
|
+
end
|
198
|
+
|
199
|
+
system "#{ sudo } #{ $ruby } pre-install.rb" if test(?s, 'pre-install.rb')
|
200
|
+
|
201
|
+
unless no_linkify
|
202
|
+
linked = linkify('lib') + linkify('bin')
|
203
|
+
end
|
204
|
+
|
205
|
+
system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
|
206
|
+
|
207
|
+
install_rb(LIBDIR, libdir, LIBDIR_MODE)
|
208
|
+
install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
|
209
|
+
|
210
|
+
if linked
|
211
|
+
linked.each{|path| File::rm_f path}
|
212
|
+
end
|
213
|
+
|
214
|
+
system "#{ sudo } #{ $ruby } post-install.rb" if test(?s, 'post-install.rb')
|
data/lib/forkoff.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Enumerable
|
4
|
+
|
5
|
+
def forkoff options = {}, &block
|
6
|
+
n = Integer( options['processes'] || options[:processes] || 8 )
|
7
|
+
done = Object.new
|
8
|
+
qs = Array.new(n){ Queue.new }
|
9
|
+
results = Array.new(n){ Queue.new }
|
10
|
+
|
11
|
+
#
|
12
|
+
# consumers
|
13
|
+
#
|
14
|
+
threads = []
|
15
|
+
|
16
|
+
n.times do |i|
|
17
|
+
thread =
|
18
|
+
Thread.new(i) do |i|
|
19
|
+
Thread.current.abort_on_exception = true
|
20
|
+
|
21
|
+
loop do
|
22
|
+
value = qs[i].pop
|
23
|
+
break if value == done
|
24
|
+
args, index = value
|
25
|
+
|
26
|
+
r, w = IO.pipe
|
27
|
+
pid = fork
|
28
|
+
|
29
|
+
unless pid
|
30
|
+
r.close
|
31
|
+
result =
|
32
|
+
begin
|
33
|
+
block.call(*args)
|
34
|
+
rescue Object => e
|
35
|
+
e
|
36
|
+
end
|
37
|
+
w.write( Marshal.dump( result ) )
|
38
|
+
exit
|
39
|
+
end
|
40
|
+
|
41
|
+
w.close
|
42
|
+
result = Marshal.load( r.read )
|
43
|
+
results[i].push( [result, index] )
|
44
|
+
Process.waitpid pid
|
45
|
+
end
|
46
|
+
|
47
|
+
results[i].push( done )
|
48
|
+
end
|
49
|
+
|
50
|
+
threads << thread
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# producer
|
55
|
+
#
|
56
|
+
each_with_index do |args, i|
|
57
|
+
qs[ i.modulo(qs.size) ].push( [args, i] )
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# mark the end of each queue
|
62
|
+
#
|
63
|
+
qs.each do |q|
|
64
|
+
q.push done
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# wait for all threads to complete
|
69
|
+
#
|
70
|
+
threads.each do |t|
|
71
|
+
t.value
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# gather results
|
76
|
+
#
|
77
|
+
list = []
|
78
|
+
|
79
|
+
results.each do |q|
|
80
|
+
loop do
|
81
|
+
value = q.pop
|
82
|
+
break if value == done
|
83
|
+
result, index = value
|
84
|
+
list[index] = result
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
list
|
89
|
+
end
|
90
|
+
|
91
|
+
alias_method 'forkoff!', 'forkoff'
|
92
|
+
end
|
data/samples/a.rb
ADDED
data/samples/b.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#
|
2
|
+
# for example, this takes only 1 second or so to complete
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'forkoff'
|
6
|
+
|
7
|
+
a = Time.now.to_f
|
8
|
+
|
9
|
+
results =
|
10
|
+
(0..7).forkoff do |i|
|
11
|
+
|
12
|
+
sleep 1
|
13
|
+
|
14
|
+
i ** 2
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
b = Time.now.to_f
|
19
|
+
|
20
|
+
elapsed = b - a
|
21
|
+
|
22
|
+
puts "elapsed: #{ elapsed }"
|
23
|
+
puts "results: #{ results.inspect }"
|
data/samples/c.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#
|
2
|
+
# forkoff does *NOT* spawn processes in batches, waiting for each batch to
|
3
|
+
# complete. rather, it keeps a certain number of processes busy until all
|
4
|
+
# results have been gathered. in otherwords the following will ensure that 2
|
5
|
+
# processes are running at all times, until the list is complete. note that
|
6
|
+
# the following will take about 2 seconds to run (2 sets of 2 @ 1 second).
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'forkoff'
|
10
|
+
|
11
|
+
pid = Process.pid
|
12
|
+
|
13
|
+
a = Time.now.to_f
|
14
|
+
|
15
|
+
pstrees =
|
16
|
+
%w( a b c d ).forkoff! :processes => 2 do |letter|
|
17
|
+
sleep 1
|
18
|
+
{ letter => ` pstree -l 2 #{ pid } ` }
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
b = Time.now.to_f
|
23
|
+
|
24
|
+
puts
|
25
|
+
puts "pid: #{ pid }"
|
26
|
+
puts "elapsed: #{ b - a }"
|
27
|
+
puts
|
28
|
+
|
29
|
+
require 'yaml'
|
30
|
+
|
31
|
+
pstrees.each do |pstree|
|
32
|
+
y pstree
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: forkoff
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ara T. Howard
|
8
|
+
autorequire: forkoff
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-04-17 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: ara.t.howard@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- gemspec.rb
|
26
|
+
- gen_readme.rb
|
27
|
+
- install.rb
|
28
|
+
- lib
|
29
|
+
- lib/forkoff.rb
|
30
|
+
- README
|
31
|
+
- samples
|
32
|
+
- samples/a.rb
|
33
|
+
- samples/b.rb
|
34
|
+
- samples/c.rb
|
35
|
+
has_rdoc: false
|
36
|
+
homepage: http://codeforpeople.com/lib/ruby/forkoff/
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
requirements: []
|
55
|
+
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 1.0.1
|
58
|
+
signing_key:
|
59
|
+
specification_version: 2
|
60
|
+
summary: forkoff
|
61
|
+
test_files: []
|
62
|
+
|