ZenHacks 1.0.0 → 1.0.1
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/History.txt +15 -0
- data/Manifest.txt +3 -0
- data/README.txt +5 -0
- data/ZenHacks.gemspec +39 -0
- data/bin/nopaste +74 -0
- data/bin/parse_tree_graph +2 -8
- data/bin/quickbench +43 -0
- data/lib/graph.rb +19 -7
- data/lib/r2c_hacks.rb +13 -3
- data/lib/ruby2ruby.rb +53 -5
- data/lib/zenoptimize.rb +24 -20
- data/zendebug-demo.sh +1 -1
- metadata +43 -6
data/History.txt
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
*** 1.0.1 / 2005-07-13
|
2
|
+
|
3
|
+
+ 4 minor enhancements:
|
4
|
+
+ Added Graph#save and edge accessors for customizations.
|
5
|
+
+ Added Proc#to_ruby in r2c_hacks.
|
6
|
+
+ Added RubyToRuby#rewrite_defn to support bmethods (read: procs).
|
7
|
+
+ Added Class#optimize(*methods) to zenoptimize.
|
8
|
+
+ Added bin/nopaste for cmdline access to nopaste on rafb.net.
|
9
|
+
+ Added bin/quickbench to generate ruby benchmark templates quickly.
|
10
|
+
+ 4 bug fixes:
|
11
|
+
+ Fixed gems for non-gem systems.
|
12
|
+
+ Fixed minor output problem with RubyToRuby#process_defn.
|
13
|
+
+ Added some minor (performance) enhancements to zenoptimize.
|
14
|
+
+ Added requirements to gemspec to quell whining.
|
15
|
+
|
1
16
|
*** 1.0.0 / 2005-05-24
|
2
17
|
|
3
18
|
+ 1 major enhancement
|
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
@@ -4,6 +4,11 @@ ZenHacks
|
|
4
4
|
|
5
5
|
** DESCRIPTION:
|
6
6
|
|
7
|
+
A cornucopia of hackery. Toys, Tricks and Tools that have spawned out
|
8
|
+
of my other projects (RubyInline, ParseTree, Ruby2C, etc) but don't
|
9
|
+
exactly fit there. This includes ZenDebugger, ZenProfiler,
|
10
|
+
ZenOptimizer, ruby2ruby, and more.
|
11
|
+
|
7
12
|
ZenHacks is a semi-random collection of libs and scripts that just
|
8
13
|
don't belong in a package of their own. Many, if not most, have
|
9
14
|
dependencies on other packages and use, abuse, or extend them in
|
data/ZenHacks.gemspec
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
spec = Gem::Specification.new do |s|
|
6
|
+
|
7
|
+
s.name = 'ZenHacks'
|
8
|
+
s.version = '1.0.1'
|
9
|
+
s.summary = "Tools and toys of mine that don't have a better home."
|
10
|
+
|
11
|
+
paragraphs = File.read("README.txt").split(/\n\n+/)
|
12
|
+
s.description = paragraphs[3]
|
13
|
+
puts s.description
|
14
|
+
|
15
|
+
s.add_dependency('RubyInline')
|
16
|
+
s.add_dependency('ParseTree')
|
17
|
+
s.add_dependency('RubyToC')
|
18
|
+
|
19
|
+
all_files = IO.readlines("Manifest.txt").map {|f| f.chomp }
|
20
|
+
s.files = all_files
|
21
|
+
|
22
|
+
s.bindir = "bin"
|
23
|
+
s.executables = all_files.grep(%r%bin/%).map { |f| File.basename(f) }
|
24
|
+
puts "Executables = #{s.executables.join(", ")}"
|
25
|
+
|
26
|
+
s.require_path = 'lib'
|
27
|
+
|
28
|
+
s.has_rdoc = false # I SUCK - TODO
|
29
|
+
|
30
|
+
s.author = "Ryan Davis"
|
31
|
+
s.email = "ryand-ruby@zenspider.com"
|
32
|
+
s.homepage = "http://rubyforge.org/projects/zenhacks/"
|
33
|
+
s.rubyforge_project = "zenhacks"
|
34
|
+
end
|
35
|
+
|
36
|
+
if $0 == __FILE__
|
37
|
+
Gem.manage_gems
|
38
|
+
Gem::Builder.new(spec).build
|
39
|
+
end
|
data/bin/nopaste
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/local/bin/ruby -sw
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'pp'
|
5
|
+
require 'cgi'
|
6
|
+
|
7
|
+
languages = %w(C90 C C++ C\# Java Pascal Perl PHP PL/I Python Ruby SQL VB XML Plain\ Text)
|
8
|
+
default_language = languages.last
|
9
|
+
tab_values = %w(No 2 3 4 5 6 8)
|
10
|
+
|
11
|
+
$l ||= default_language
|
12
|
+
$n ||= ""
|
13
|
+
$s ||= ""
|
14
|
+
$t ||= tab_values.first
|
15
|
+
|
16
|
+
lang = $l
|
17
|
+
nickname = $n
|
18
|
+
description = $s
|
19
|
+
tabs = $t
|
20
|
+
|
21
|
+
text =
|
22
|
+
if ARGV.empty? then
|
23
|
+
$stdin.read
|
24
|
+
else
|
25
|
+
File.read(ARGV.shift)
|
26
|
+
end
|
27
|
+
|
28
|
+
data = {
|
29
|
+
:lang => lang,
|
30
|
+
:nick => nickname,
|
31
|
+
:desc => description,
|
32
|
+
:cvt_tabs => tabs,
|
33
|
+
:text => text,
|
34
|
+
}
|
35
|
+
|
36
|
+
order = %w(lang nick desc cvt_tabs text).map { |s| s.intern }
|
37
|
+
data = order.map { |k|
|
38
|
+
v=data[k]
|
39
|
+
"#{CGI::escape k.to_s}=#{CGI::escape v}"
|
40
|
+
}.join('&')
|
41
|
+
|
42
|
+
headers = {
|
43
|
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
44
|
+
'Referer' => 'http://www.rafb.net/paste/index.html',
|
45
|
+
'Host' => 'www.rafb.net',
|
46
|
+
'Accept' => 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, image/tiff, multipart/x-mixed-replace, */*;q=0.1',
|
47
|
+
'Accept-Encoding' => 'bzip2, gzip, deflate, identity',
|
48
|
+
'Accept-Charset' => 'iso-8859-1, utf-8, iso-10646-ucs-2, macintosh, windows-1252, *',
|
49
|
+
'Accept-Language' => 'en, fr;q=0.94, ja;q=0.88, it;q=0.81, de;q=0.75, es;q=0.69, nl;q=0.62, sv;q=0.56, no;q=0.50, da;q=0.44, fi;q=0.38, pt;q=0.31, zh-cn;q=0.25, zh-tw;q=0.19, ko;q=0.12',
|
50
|
+
'Pragma' => 'no-cache',
|
51
|
+
'Cache-Control' => 'max-age=0',
|
52
|
+
'Connection' => 'Keep-Alive',
|
53
|
+
'User-Agent' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-US) AppleWebKit/125.4 (KHTML, like Gecko, Safari) OmniWeb/v563.34',
|
54
|
+
}
|
55
|
+
|
56
|
+
Net::HTTP.start('www.rafb.net', 80) { |http|
|
57
|
+
response = http.post('/paste/paste.php', data, headers)
|
58
|
+
|
59
|
+
location = response['location']
|
60
|
+
|
61
|
+
if location then
|
62
|
+
puts "http://www.rafb.net#{location}"
|
63
|
+
else
|
64
|
+
puts "ERROR:"
|
65
|
+
puts "header:"
|
66
|
+
p response.header
|
67
|
+
puts
|
68
|
+
puts "body:"
|
69
|
+
puts response.body
|
70
|
+
puts "code/message:"
|
71
|
+
puts response.code
|
72
|
+
puts response.message
|
73
|
+
end
|
74
|
+
}
|
data/bin/parse_tree_graph
CHANGED
@@ -17,14 +17,8 @@ end
|
|
17
17
|
|
18
18
|
usage if defined? $h
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
# require 'rubygems'
|
23
|
-
# require_gem 'ParseTree'
|
24
|
-
#rescue LoadError
|
25
|
-
require 'parse_tree'
|
26
|
-
#end
|
27
|
-
|
20
|
+
begin require 'rubygems' rescue LoadError end
|
21
|
+
require 'parse_tree'
|
28
22
|
require 'sexp_processor'
|
29
23
|
|
30
24
|
def discover_new_classes_from
|
data/bin/quickbench
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# TODO: while you are doing this, add an emacs method that toggles
|
4
|
+
# between test file and implementation!
|
5
|
+
|
6
|
+
def usage
|
7
|
+
puts "quickbench number-of-benchmarks"
|
8
|
+
exit 1
|
9
|
+
end
|
10
|
+
|
11
|
+
# path = ARGV.shift || usage
|
12
|
+
count = ARGV.shift.to_i || usage
|
13
|
+
usage unless ARGV.empty?
|
14
|
+
|
15
|
+
require 'benchmark'
|
16
|
+
|
17
|
+
print <<EOM
|
18
|
+
require 'benchmark'
|
19
|
+
|
20
|
+
MAX=1_000_000
|
21
|
+
|
22
|
+
Benchmark::bm(20) do |x|
|
23
|
+
x.report("null_time") {
|
24
|
+
for i in 0..MAX do
|
25
|
+
# do nothing
|
26
|
+
end
|
27
|
+
}
|
28
|
+
|
29
|
+
EOM
|
30
|
+
|
31
|
+
count.times do |n|
|
32
|
+
print <<"EOM"
|
33
|
+
x.report("benchmark-#{n+1}") {
|
34
|
+
for i in 0..MAX do
|
35
|
+
# insert code here
|
36
|
+
end
|
37
|
+
}
|
38
|
+
|
39
|
+
EOM
|
40
|
+
end
|
41
|
+
|
42
|
+
puts "end"
|
43
|
+
|
data/lib/graph.rb
CHANGED
@@ -5,11 +5,13 @@ class Graph < Hash
|
|
5
5
|
attr_reader :attribs
|
6
6
|
attr_reader :prefix
|
7
7
|
attr_reader :order
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
attr_reader :edge
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
super { |h,k| h[k] = [] }
|
11
12
|
@prefix = []
|
12
13
|
@attribs = Hash.new { |h,k| h[k] = [] }
|
14
|
+
@edge = Hash.new { |h,k| h[k] = Hash.new { |h2,k2| h2[k2] = [] } }
|
13
15
|
@order = []
|
14
16
|
end
|
15
17
|
|
@@ -25,7 +27,7 @@ class Graph < Hash
|
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
28
|
-
|
30
|
+
|
29
31
|
def invert
|
30
32
|
result = self.class.new
|
31
33
|
each_pair do |from, to|
|
@@ -41,14 +43,14 @@ class Graph < Hash
|
|
41
43
|
end
|
42
44
|
result
|
43
45
|
end
|
44
|
-
|
46
|
+
|
45
47
|
def keys_by_count
|
46
48
|
counts.sort_by { |x,y| y }.map {|x| x.first }
|
47
49
|
end
|
48
50
|
|
49
51
|
def to_s
|
50
52
|
result = []
|
51
|
-
result << "digraph
|
53
|
+
result << "digraph absent"
|
52
54
|
result << " {"
|
53
55
|
@prefix.each do |line|
|
54
56
|
result << line
|
@@ -57,10 +59,20 @@ class Graph < Hash
|
|
57
59
|
result << " #{node.inspect} [ #{attribs.join(',')} ]"
|
58
60
|
end
|
59
61
|
each_pair do |from, to|
|
60
|
-
|
62
|
+
edge = @edge[from][to].join(", ")
|
63
|
+
edge = " [ #{edge} ]" unless edge.empty?
|
64
|
+
result << " #{from.inspect} -> #{to.inspect}#{edge};"
|
61
65
|
end
|
62
66
|
result << " }"
|
63
67
|
result.join("\n")
|
64
68
|
end
|
65
69
|
|
70
|
+
def save(path, type="png")
|
71
|
+
File.open(path + ".dot", "w") do |f|
|
72
|
+
f.puts self.to_s
|
73
|
+
f.flush
|
74
|
+
cmd = "/usr/local/bin/dot -T#{type} #{path}.dot > #{path}.#{type}"
|
75
|
+
system cmd
|
76
|
+
end
|
77
|
+
end
|
66
78
|
end
|
data/lib/r2c_hacks.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
#require_gem 'ParseTree'
|
1
|
+
begin require 'rubygems' rescue LoadError end
|
3
2
|
require 'parse_tree'
|
4
3
|
require 'sexp_processor'
|
5
4
|
require 'ruby_to_c'
|
@@ -10,6 +9,7 @@ class Method
|
|
10
9
|
if self.inspect =~ /<Method: (.*)\#(.*)>/ then
|
11
10
|
klass = eval $1
|
12
11
|
method = $2.intern
|
12
|
+
raise "Couldn't determine class from #{self.inspect}" if klass.nil?
|
13
13
|
return yield(klass, method)
|
14
14
|
else
|
15
15
|
raise "Can't parse signature: #{self.inspect}"
|
@@ -18,7 +18,7 @@ class Method
|
|
18
18
|
|
19
19
|
def to_sexp
|
20
20
|
with_class_and_method_name do |klass, method|
|
21
|
-
ParseTree.new.parse_tree_for_method(klass, method)
|
21
|
+
ParseTree.new(false).parse_tree_for_method(klass, method)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -34,3 +34,13 @@ class Method
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
37
|
+
|
38
|
+
class Proc
|
39
|
+
ProcStoreTmp = Class.new unless defined? ProcStoreTmp
|
40
|
+
def to_ruby
|
41
|
+
ProcStoreTmp.send(:define_method, :myproc, self)
|
42
|
+
m = ProcStoreTmp.new.method(:myproc)
|
43
|
+
result = m.to_ruby.sub!(/def myproc\(([^\)]+)\)/, 'proc do |\1|')
|
44
|
+
return result
|
45
|
+
end
|
46
|
+
end
|
data/lib/ruby2ruby.rb
CHANGED
@@ -6,9 +6,9 @@ class RubyToRuby < SexpProcessor
|
|
6
6
|
|
7
7
|
def self.translate(klass, method=nil)
|
8
8
|
unless method.nil? then
|
9
|
-
self.new.process(ParseTree.new.parse_tree_for_method(klass, method))
|
9
|
+
self.new.process(ParseTree.new(false).parse_tree_for_method(klass, method))
|
10
10
|
else
|
11
|
-
self.new.process(ParseTree.new.parse_tree(klass).first) # huh? why is the :class node wrapped?
|
11
|
+
self.new.process(ParseTree.new(false).parse_tree(klass).first) # huh? why is the :class node wrapped?
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -115,14 +115,62 @@ class RubyToRuby < SexpProcessor
|
|
115
115
|
def process_dasgn_curr(exp)
|
116
116
|
exp.shift.to_s
|
117
117
|
end
|
118
|
+
|
119
|
+
def rewrite_defn(exp)
|
120
|
+
exp.shift # :defn
|
121
|
+
name = exp.shift
|
122
|
+
args = s(:args)
|
123
|
+
body = Sexp.from_array exp.shift
|
124
|
+
|
125
|
+
case body.first
|
126
|
+
when :scope, :fbody then
|
127
|
+
body = body[1] if body.first == :fbody
|
128
|
+
args = body.last[1]
|
129
|
+
assert_type args, :args
|
130
|
+
assert_type body, :scope
|
131
|
+
assert_type body[1], :block
|
132
|
+
body.last.delete_at 1
|
133
|
+
when :bmethod then
|
134
|
+
# BEFORE: [:defn, :bmethod_added, [:bmethod, [:dasgn_curr, :x], ...]]
|
135
|
+
# AFTER: [:defn, :bmethod_added, [:args, :x], [:scope, [:block, ...]]]
|
136
|
+
body.shift # :bmethod
|
137
|
+
# [:dasgn_curr, :x],
|
138
|
+
# [:call, [:dvar, :x], :+, [:arglist, [:lit, 1]]]]]
|
139
|
+
dasgn = body.shift
|
140
|
+
assert_type dasgn, :dasgn_curr
|
141
|
+
dasgn.shift # type
|
142
|
+
args.push(*dasgn)
|
143
|
+
body.find_and_replace_all(:dvar, :lvar)
|
144
|
+
if body.first.first == :block then
|
145
|
+
body = s(:scope, body.shift)
|
146
|
+
else
|
147
|
+
body = s(:scope, s(:block, body.shift)) # single statement
|
148
|
+
end
|
149
|
+
when :dmethod
|
150
|
+
# BEFORE: [:defn, :dmethod_added, [:dmethod, :bmethod_maker, ...]]
|
151
|
+
# AFTER: [:defn, :dmethod_added, ...]
|
152
|
+
body = body[2][1][2] # UGH! FIX
|
153
|
+
args = body[1]
|
154
|
+
body.delete_at 1
|
155
|
+
body = s(:scope, body)
|
156
|
+
when :ivar then
|
157
|
+
body = s(:scope, s(:block, s(:return, body)))
|
158
|
+
when :attrset then
|
159
|
+
argname = body.last
|
160
|
+
args << :arg
|
161
|
+
body = s(:scope, s(:block, s(:return, s(:iasgn, argname, s(:lvar, :arg)))))
|
162
|
+
else
|
163
|
+
raise "Unknown :defn format: #{name.inspect} #{args.inspect} #{body.inspect}"
|
164
|
+
end
|
165
|
+
|
166
|
+
return s(:defn, name, args, body)
|
167
|
+
end
|
118
168
|
|
119
169
|
def process_defn(exp)
|
120
170
|
name = exp.shift
|
121
171
|
args = process(exp.shift).to_a
|
122
|
-
args[1..-1] = indent(args[1..-1])
|
123
|
-
args.join
|
124
172
|
body = indent(process(exp.shift))
|
125
|
-
return "def #{name}#{args}#{body}end".gsub(/\n\s*\n+/, "\n")
|
173
|
+
return "def #{name}#{args}\n#{body}end".gsub(/\n\s*\n+/, "\n")
|
126
174
|
end
|
127
175
|
|
128
176
|
def process_dot2(exp)
|
data/lib/zenoptimize.rb
CHANGED
@@ -1,7 +1,19 @@
|
|
1
|
-
require '
|
1
|
+
begin require 'rubygems' rescue LoadError end
|
2
2
|
require 'singleton'
|
3
|
-
require '
|
3
|
+
require 'inline'
|
4
4
|
require 'pp'
|
5
|
+
require 'ruby_to_c'
|
6
|
+
|
7
|
+
class Class
|
8
|
+
def optimize(*methods)
|
9
|
+
methods.each do |method|
|
10
|
+
src = RubyToC.translate(self, method)
|
11
|
+
class_eval "alias :#{method}_slow :#{method}"
|
12
|
+
class_eval "remove_method :#{method}"
|
13
|
+
class_eval "inline(:C) { |b| b.c src }"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
5
17
|
|
6
18
|
module Inline
|
7
19
|
class Ruby < Inline::C
|
@@ -23,6 +35,7 @@ class ZenOptimizer
|
|
23
35
|
|
24
36
|
include Singleton
|
25
37
|
|
38
|
+
@@signature = :fuck
|
26
39
|
@@threshold = 500
|
27
40
|
@@sacred = {
|
28
41
|
Sexp => true,
|
@@ -30,6 +43,9 @@ class ZenOptimizer
|
|
30
43
|
@@skip = Hash.new(false)
|
31
44
|
@@data = Hash.new(0)
|
32
45
|
|
46
|
+
def self.data; @@data; end
|
47
|
+
def self.signature; @@signature; end
|
48
|
+
|
33
49
|
def self.start_optimizing
|
34
50
|
self.instance.add_event_hook
|
35
51
|
end
|
@@ -80,6 +96,8 @@ static unsigned long threshold = 0;"
|
|
80
96
|
prof_event_hook(rb_event_t event, NODE *node,
|
81
97
|
VALUE self, ID mid, VALUE klass) {
|
82
98
|
|
99
|
+
static int optimizing = 0;
|
100
|
+
|
83
101
|
if (NIL_P(optimizer_klass))
|
84
102
|
optimizer_klass = rb_path2class("ZenOptimizer");
|
85
103
|
if (NIL_P(data))
|
@@ -88,34 +106,19 @@ static unsigned long threshold = 0;"
|
|
88
106
|
skip = rb_cv_get(optimizer_klass, "@@skip");
|
89
107
|
if (threshold == 0)
|
90
108
|
threshold = NUM2ULONG(rb_cv_get(optimizer_klass, "@@threshold"));
|
109
|
+
if (optimizing) return;
|
110
|
+
optimizing++;
|
91
111
|
|
92
112
|
switch (event) {
|
93
113
|
case RUBY_EVENT_CALL:
|
94
114
|
{
|
95
115
|
VALUE signature;
|
96
116
|
|
97
|
-
#if 0
|
98
|
-
VALUE mod_name = rb_mod_name(klass);
|
99
|
-
if (NIL_P(mod_name))
|
100
|
-
signature = rb_str_new2("Unknown");
|
101
|
-
else
|
102
|
-
signature = mod_name;
|
103
|
-
|
104
|
-
rb_str_cat(signature, ".", 1); // TODO: # or .
|
105
|
-
|
106
|
-
char * meth = rb_id2name(mid);
|
107
|
-
if (meth) {
|
108
|
-
size_t len = strlen(meth);
|
109
|
-
rb_str_cat(signature, meth, len);
|
110
|
-
} else {
|
111
|
-
rb_str_cat(signature, "unknown", 7);
|
112
|
-
}
|
113
|
-
#else
|
114
117
|
signature = rb_ary_new2(2);
|
115
118
|
rb_ary_store(signature, 0, klass);
|
116
119
|
rb_ary_store(signature, 1, ID2SYM(mid));
|
117
|
-
#endif
|
118
120
|
|
121
|
+
rb_cv_set(optimizer_klass, "@@signature", signature);
|
119
122
|
unsigned long count = NUM2ULONG(rb_hash_aref(data, signature)) + 1;
|
120
123
|
|
121
124
|
if (count > threshold) {
|
@@ -128,6 +131,7 @@ static unsigned long threshold = 0;"
|
|
128
131
|
}
|
129
132
|
break;
|
130
133
|
}
|
134
|
+
optimizing--;
|
131
135
|
}
|
132
136
|
EOF
|
133
137
|
|
data/zendebug-demo.sh
CHANGED
metadata
CHANGED
@@ -3,15 +3,18 @@ rubygems_version: 0.8.10.1
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ZenHacks
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.0.
|
7
|
-
date: 2005-
|
6
|
+
version: 1.0.1
|
7
|
+
date: 2005-07-14
|
8
8
|
summary: "Tools and toys of mine that don't have a better home."
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
email: ryand-ruby@zenspider.com
|
12
12
|
homepage: http://rubyforge.org/projects/zenhacks/
|
13
13
|
rubyforge_project: zenhacks
|
14
|
-
description: "
|
14
|
+
description: "This package is not supported in the same sense that my other packages are, but
|
15
|
+
since it is such a fun playground, I am very open to contributions, suggestions,
|
16
|
+
and bug fixes. I just can't put this project at the top of my priority list the
|
17
|
+
way I can/do the others, so it may take me longer to get to than normal."
|
15
18
|
autorequire:
|
16
19
|
default_executable:
|
17
20
|
bindir: bin
|
@@ -30,8 +33,11 @@ files:
|
|
30
33
|
- History.txt
|
31
34
|
- Manifest.txt
|
32
35
|
- README.txt
|
36
|
+
- ZenHacks.gemspec
|
33
37
|
- bin/macgraph
|
38
|
+
- bin/nopaste
|
34
39
|
- bin/parse_tree_graph
|
40
|
+
- bin/quickbench
|
35
41
|
- bin/test_stats
|
36
42
|
- fixloops-demo.sh
|
37
43
|
- lib/OrderedHash.rb
|
@@ -61,9 +67,40 @@ rdoc_options: []
|
|
61
67
|
extra_rdoc_files: []
|
62
68
|
executables:
|
63
69
|
- macgraph
|
70
|
+
- nopaste
|
64
71
|
- parse_tree_graph
|
72
|
+
- quickbench
|
65
73
|
- test_stats
|
66
74
|
extensions: []
|
67
|
-
requirements:
|
68
|
-
|
69
|
-
|
75
|
+
requirements: []
|
76
|
+
dependencies:
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: RubyInline
|
79
|
+
version_requirement:
|
80
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
81
|
+
requirements:
|
82
|
+
-
|
83
|
+
- ">"
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 0.0.0
|
86
|
+
version:
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: ParseTree
|
89
|
+
version_requirement:
|
90
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
91
|
+
requirements:
|
92
|
+
-
|
93
|
+
- ">"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 0.0.0
|
96
|
+
version:
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: RubyToC
|
99
|
+
version_requirement:
|
100
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
101
|
+
requirements:
|
102
|
+
-
|
103
|
+
- ">"
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: 0.0.0
|
106
|
+
version:
|