gratr19 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README +335 -0
- data/examples/graph_self.rb +54 -0
- data/examples/module_graph.jpg +0 -0
- data/examples/module_graph.rb +12 -0
- data/examples/self_graph.jpg +0 -0
- data/examples/visualize.jpg +0 -0
- data/examples/visualize.rb +8 -0
- data/install.rb +49 -0
- data/lib/gratr.rb +42 -0
- data/lib/gratr/adjacency_graph.rb +230 -0
- data/lib/gratr/base.rb +34 -0
- data/lib/gratr/biconnected.rb +116 -0
- data/lib/gratr/chinese_postman.rb +123 -0
- data/lib/gratr/common.rb +74 -0
- data/lib/gratr/comparability.rb +92 -0
- data/lib/gratr/digraph.rb +115 -0
- data/lib/gratr/digraph_distance.rb +185 -0
- data/lib/gratr/dot.rb +90 -0
- data/lib/gratr/edge.rb +145 -0
- data/lib/gratr/graph.rb +314 -0
- data/lib/gratr/graph_api.rb +82 -0
- data/lib/gratr/import.rb +44 -0
- data/lib/gratr/labels.rb +103 -0
- data/lib/gratr/maximum_flow.rb +107 -0
- data/lib/gratr/rdot.rb +332 -0
- data/lib/gratr/search.rb +422 -0
- data/lib/gratr/strong_components.rb +127 -0
- data/lib/gratr/undirected_graph.rb +153 -0
- data/lib/gratr/version.rb +6 -0
- data/lib/priority-queue/benchmark/dijkstra.rb +171 -0
- data/lib/priority-queue/compare_comments.rb +49 -0
- data/lib/priority-queue/ext/priority_queue/CPriorityQueue/extconf.rb +2 -0
- data/lib/priority-queue/lib/priority_queue.rb +14 -0
- data/lib/priority-queue/lib/priority_queue/c_priority_queue.rb +1 -0
- data/lib/priority-queue/lib/priority_queue/poor_priority_queue.rb +46 -0
- data/lib/priority-queue/lib/priority_queue/ruby_priority_queue.rb +525 -0
- data/lib/priority-queue/setup.rb +1551 -0
- data/lib/priority-queue/test/priority_queue_test.rb +371 -0
- data/tests/TestBiconnected.rb +53 -0
- data/tests/TestChinesePostman.rb +53 -0
- data/tests/TestComplement.rb +54 -0
- data/tests/TestDigraph.rb +333 -0
- data/tests/TestDigraphDistance.rb +138 -0
- data/tests/TestDot.rb +75 -0
- data/tests/TestEdge.rb +171 -0
- data/tests/TestInspection.rb +57 -0
- data/tests/TestMultiEdge.rb +57 -0
- data/tests/TestNeighborhood.rb +64 -0
- data/tests/TestProperties.rb +160 -0
- data/tests/TestSearch.rb +277 -0
- data/tests/TestStrongComponents.rb +85 -0
- data/tests/TestTriagulated.rb +137 -0
- data/tests/TestUndirectedGraph.rb +219 -0
- metadata +152 -0
data/README
ADDED
@@ -0,0 +1,335 @@
|
|
1
|
+
= GRAph Theory in Ruby (GRATR)
|
2
|
+
|
3
|
+
link:../gratr.jpg GRATR is a framework for graph data structures and algorithms.
|
4
|
+
|
5
|
+
This project is a fork of Horst Duchene's RGL library.
|
6
|
+
|
7
|
+
The design of the library is much influenced by the Boost Graph Library (BGL)
|
8
|
+
which is written in C++ heavily using its template mechanism. Refer to
|
9
|
+
http://www.boost.org/libs/graph/doc for further links and documentation on graph
|
10
|
+
data structures and algorithms and the design rationales of BGL.
|
11
|
+
|
12
|
+
A comprehensive summary of graph terminology can be found in the the graph
|
13
|
+
section of the <em>Dictionary of Algorithms and Data Structures</em> at
|
14
|
+
http://www.nist.gov/dads/HTML/graph.html.
|
15
|
+
|
16
|
+
There are two Arc classes, GRATR::Arc and GRATR::Edge.
|
17
|
+
|
18
|
+
GRATR::Digraph and it's pseudonym GRATR::DirectedGraph are classes that have single directed edges
|
19
|
+
between vertices and loops are forbidden. GRATR::DirectedPseudoGraph allows for
|
20
|
+
multiple directed edges between vertices and loops are forbidden.
|
21
|
+
GRATR::DirectedMultiGraph allows for multiple directed edges between vertices and
|
22
|
+
loops on vertices.
|
23
|
+
|
24
|
+
GRATR::UndirectedGraph, GRATR::UndirectedPseudoGraph and GRATR::UndirectedMultiGraph are similar
|
25
|
+
but all edges are undirected.
|
26
|
+
|
27
|
+
These classes are all available with a <tt>require 'gratr'</tt> statement in your Ruby code. If one wishes
|
28
|
+
to pull the classes into the current namespace, i.e. drop the <tt>GRATR::</tt> from all
|
29
|
+
class statements and use <tt>require 'gratr/import'</tt> instead.
|
30
|
+
|
31
|
+
== Design principles
|
32
|
+
|
33
|
+
This document concentrates on the special issues of the implementation in
|
34
|
+
Ruby. The main design goals directly taken from the BGL design are:
|
35
|
+
|
36
|
+
* An interface for how the structure of a graph can be accessed using a generic
|
37
|
+
interface that hides the details of the graph data structure
|
38
|
+
implementation. This interface is defined by the module Graph, which should be
|
39
|
+
included in concrete classes.
|
40
|
+
|
41
|
+
* A standardized generic interface for traversing graphs using standard
|
42
|
+
Ruby block iterators.
|
43
|
+
|
44
|
+
* Implementation is separated from interface, and hidden from the average user.
|
45
|
+
An advanced user could also easily override the internals with a different
|
46
|
+
implementation if need be.
|
47
|
+
|
48
|
+
GRATR provides some general purpose graph classes that conform to this interface,
|
49
|
+
but they are not meant to be the *only* graph classes. As in BGL I believe that
|
50
|
+
the main contribution of the GRATR is the formulation of this interface.
|
51
|
+
|
52
|
+
The BGL graph interface and graph components are generic in the sense of the C++
|
53
|
+
Standard Template Library (STL). In Ruby other techniques are available to
|
54
|
+
express the generic character of the algorithms and data structures mainly using
|
55
|
+
mixins and iterators. The BGL documentation mentions three means to achieve
|
56
|
+
genericity:
|
57
|
+
|
58
|
+
* Algorithm/Data-Structure Interoperability
|
59
|
+
* Extension through Function Objects and Visitors
|
60
|
+
* Element Type Parameterization
|
61
|
+
* Vertex and Arc Property Multi-Parameterization
|
62
|
+
|
63
|
+
The first is easily achieved in GRATR using mixins, which of course is not as
|
64
|
+
efficient than C++ templates (but much more readable :-). The second one is
|
65
|
+
even more easily implemented using standard iterators with blocks.
|
66
|
+
The third one is no issue since Ruby is dynamically typed: Each object can
|
67
|
+
be a graph vertex (even nil!). There is no need for a vertex (or even edge type). A
|
68
|
+
label interface is provided for end users as well. One could simply use
|
69
|
+
a hash externally, but the future development of network graphs will require
|
70
|
+
a weight or capacity property to be accessible.
|
71
|
+
|
72
|
+
=== Algorithms
|
73
|
+
|
74
|
+
This version of GRATR contains a core set of algorithm patterns:
|
75
|
+
|
76
|
+
* Breadth First Search Graph[1,2,1,3,1,4,2,5].bfs => [1, 2, 3, 4, 5]
|
77
|
+
* Depth First Search Graph[1,2,1,3,1,4,2,5].dfs => [1, 2, 5, 3, 4]
|
78
|
+
* A* Search
|
79
|
+
* Lexicographic Search
|
80
|
+
* Dijkstra's Algorithm
|
81
|
+
* Floyd-Warshall
|
82
|
+
* Triangulation and Comparability detection
|
83
|
+
|
84
|
+
The algorithm patterns by themselves do not compute any meaningful quantities
|
85
|
+
over graphs, they are merely building blocks for constructing graph
|
86
|
+
algorithms. The graph algorithms in GRATR currently include:
|
87
|
+
|
88
|
+
* Topological Sort (topsort)
|
89
|
+
* Strongly Connected Components (strong_connect)
|
90
|
+
* Transitive Closure (transitive_closure)
|
91
|
+
|
92
|
+
=== Data Structures
|
93
|
+
|
94
|
+
GRATR currently provides one graph module that implement a generalized adjacency
|
95
|
+
list and an edge list adaptor.
|
96
|
+
|
97
|
+
* GRATR::AdjacencyGraph
|
98
|
+
|
99
|
+
The GRATR::Digraph class is the general purpose *swiss army knife* of graph
|
100
|
+
classes, most of the other classes are just modifications to this class.
|
101
|
+
It is optimized for efficient access to just the out-edges, fast vertex
|
102
|
+
insertion and removal at the cost of extra space overhead, etc.
|
103
|
+
|
104
|
+
=== GEM Installation
|
105
|
+
|
106
|
+
Download the GEM file and install it with ..
|
107
|
+
|
108
|
+
% gem install gratr-VERSION.gem
|
109
|
+
|
110
|
+
or directly with
|
111
|
+
|
112
|
+
% gem install gratr
|
113
|
+
|
114
|
+
Use the correct version number for VERSION (e.g. 0.2.x). You may need root
|
115
|
+
privileges to install.
|
116
|
+
|
117
|
+
=== Running tests
|
118
|
+
|
119
|
+
GRATR comes with a Rakefile which automatically runs the tests. Goto the
|
120
|
+
installation directory and start rake:
|
121
|
+
|
122
|
+
% gem env
|
123
|
+
Rubygems Environment:
|
124
|
+
- VERSION: 0.8.3 (0.8.3)
|
125
|
+
- INSTALLATION DIRECTORY: /usr/lib/ruby/gems/1.8
|
126
|
+
- GEM PATH:
|
127
|
+
- /usr/lib/ruby/gems/1.8
|
128
|
+
- REMOTE SOURCES:
|
129
|
+
- http://gems.rubyforge.org
|
130
|
+
|
131
|
+
% cd /usr/lib/ruby/gems/1.8/gems/gratr-0.2.2/
|
132
|
+
% r40> rake
|
133
|
+
(in /usr/lib/ruby/gems/1.8/gems/gratr-0.2.2)
|
134
|
+
ruby1.8 -Ilib:tests -e0 -rtests/TestGraphXML -rtests/TestComponents -rtests/TestDirectedGraph -rtests/TestArc -rtests/TestImplicit -rtests/TestTransitiveClosure -rtests/TestTraversal -rtests/TestUnDirectedGraph
|
135
|
+
Loaded suite -e
|
136
|
+
Started
|
137
|
+
........................................................................................................
|
138
|
+
Finished in 0.736444 seconds.
|
139
|
+
|
140
|
+
40 tests, 421 assertions, 0 failures, 0 errors
|
141
|
+
|
142
|
+
=== Normal Installation
|
143
|
+
|
144
|
+
You have to install stream library before. You can than install GRATR with the
|
145
|
+
following command:
|
146
|
+
|
147
|
+
% ruby install.rb
|
148
|
+
|
149
|
+
from its distribution directory. To uninstall it use
|
150
|
+
|
151
|
+
% ruby install.rb -u
|
152
|
+
|
153
|
+
The rdoc is useful as well:
|
154
|
+
|
155
|
+
% rake rdoc
|
156
|
+
|
157
|
+
== Example irb session with GRATR
|
158
|
+
|
159
|
+
irb> require 'gratr/import'
|
160
|
+
=> true
|
161
|
+
irb> dg = Digraph[1,2, 2,3, 2,4, 4,5, 6,4, 1,6]
|
162
|
+
=> GRATR::Digraph[[2, 3], [1, 6], [2, 4], [4, 5], [1, 2], [6, 4]]
|
163
|
+
|
164
|
+
A few properties of the graph
|
165
|
+
|
166
|
+
irb> dg.directed?
|
167
|
+
=> true
|
168
|
+
irb> dg.vertex?(4)
|
169
|
+
=> true
|
170
|
+
irb> dg.edge?(2,4)
|
171
|
+
=> true
|
172
|
+
irb> dg.edge?(4,2)
|
173
|
+
=> false
|
174
|
+
irb> dg.vertices
|
175
|
+
=> [5, 6, 1, 2, 3, 4]
|
176
|
+
|
177
|
+
Every object could be a vertex (there is no class Vertex), even the class
|
178
|
+
object _Object_:
|
179
|
+
|
180
|
+
irb> dg.vertex? Object
|
181
|
+
=> false
|
182
|
+
irb> UndirectedGraph.new(dg).edges.sort.to_s
|
183
|
+
=> "(1=2)(2=3)(2=4)(4=5)(1=6)(4=6)"
|
184
|
+
|
185
|
+
Add inverse edge (4-2) to directed graph:
|
186
|
+
|
187
|
+
irb> dg.add_edge! 4,2
|
188
|
+
=> GRATR::Digraph[[2, 3], [1, 6], [4, 2], [2, 4], [4, 5], [1, 2], [6, 4]]
|
189
|
+
|
190
|
+
(4-2) == (2-4) in the undirected graph:
|
191
|
+
|
192
|
+
irb> UndirectedGraph.new(dg).edges.sort.to_s
|
193
|
+
=> "(1=2)(2=3)(2=4)(4=5)(1=6)(4=6)"
|
194
|
+
|
195
|
+
(4-2) != (2-4) in directed graphs:
|
196
|
+
|
197
|
+
irb> dg.edges.sort.to_s
|
198
|
+
=> "(1-2)(1-6)(2-3)(2-4)(4-2)(4-5)(6-4)"
|
199
|
+
irb> dg.remove_edge! 4,2
|
200
|
+
=> GRATR::Digraph[[2, 3], [1, 6], [2, 4], [4, 5], [1, 2], [6, 4]]
|
201
|
+
|
202
|
+
<em>Topological sort</em> is realized with as iterator:
|
203
|
+
|
204
|
+
irb> dg.topsort
|
205
|
+
=> [1, 2, 3, 6, 4, 5]
|
206
|
+
irb> y=0; dg.topsort {|v| y+=v}; y
|
207
|
+
=> 21
|
208
|
+
|
209
|
+
# Use DOT to visualize this graph:
|
210
|
+
irb> require 'gratr/dot'
|
211
|
+
irb> dg.write_to_graphic_file('jpg','visualize')
|
212
|
+
"graph.jpg"
|
213
|
+
|
214
|
+
The result: link:../examples/visualize.jpg
|
215
|
+
|
216
|
+
Here's an example showing the module inheritance hierarchy:
|
217
|
+
|
218
|
+
module_graph=Digraph.new
|
219
|
+
ObjectSpace.each_object(Module) do |m|
|
220
|
+
m.ancestors.each {|a| module_graph.add_edge!(m,a) if m != a}
|
221
|
+
end
|
222
|
+
|
223
|
+
gv = module_graph.vertices.select {|v| v.to_s.match(/GRATR/)}
|
224
|
+
module_graph.induced_subgraph(gv).write_to_graphic_file('jpg','module_graph')
|
225
|
+
|
226
|
+
The result: link:../examples/module_graph.jpg
|
227
|
+
|
228
|
+
Look for more in the examples directory.
|
229
|
+
|
230
|
+
== Credits
|
231
|
+
|
232
|
+
Many thanks to Robert Feldt which also worked on a graph library
|
233
|
+
(http://rockit.sf.net/subprojects/graphr) who pointed me to BGL and many other
|
234
|
+
graph resources. Manuel Simoni found a subtle bug in a preliminary version
|
235
|
+
announced at http://rubygarden.com/ruby?RubyAlgorithmPackage/Graph.
|
236
|
+
|
237
|
+
Robert kindly allowed to integrate his work on graphr, which I did not yet
|
238
|
+
succeed. Especially his work to output graphs for
|
239
|
+
GraphViz[http://www.research.att.com/sw/tools/graphviz/download.html] is much
|
240
|
+
more elaborated than the minimal support in dot.rb.
|
241
|
+
|
242
|
+
Jeremy Siek one of the authors of the nice book "The Boost Graph Library (BGL)"
|
243
|
+
(http://www.boost.org/libs/graph/doc) kindly allowed to use the
|
244
|
+
BGL documentation as a _cheap_ reference for GRATR. He and Robert also gave
|
245
|
+
feedback and many ideas for GRATR.
|
246
|
+
|
247
|
+
Dave Thomas for RDoc[http://rdoc.sourceforge.net] which generated what you read
|
248
|
+
and Matz for Ruby. Dave included in the latest version of RDoc (alpha9) the
|
249
|
+
module dot/dot.rb which I use instead of Roberts module to visualize graphs
|
250
|
+
(see gratr/dot.rb).
|
251
|
+
|
252
|
+
Horst Duchene for RGL which provided the basis for this library and his vision.
|
253
|
+
|
254
|
+
Rick Bradley who reworked the library and added many graph theoretic constructs.
|
255
|
+
|
256
|
+
== Known Bugs
|
257
|
+
|
258
|
+
* Some of the digraph distance algorithms need reworked to work for pseudo and multi graphs.
|
259
|
+
|
260
|
+
== To Do
|
261
|
+
|
262
|
+
* Primal Dual for combinatorial optimization problems
|
263
|
+
* Min-Max Flow
|
264
|
+
* Near optimal traveling salesman problem
|
265
|
+
* Orientation of undirected graphs
|
266
|
+
|
267
|
+
== Release Notes
|
268
|
+
|
269
|
+
The core interface is about to be updated to allow for cleaner dependency injects. Luke Kanies has also contributed
|
270
|
+
several optimizations for speed and logged some bugs. This will result in a 0.5 release coming soon.
|
271
|
+
|
272
|
+
=== 0.4.3
|
273
|
+
|
274
|
+
* Fixed bug in dot output dependency.
|
275
|
+
* Changed method.call to send in a couple places.
|
276
|
+
* Fixed bug in unconnected vertices for reversal. Ticket #7237
|
277
|
+
* Fixed bugs in A* Search. Ticket #7250.
|
278
|
+
|
279
|
+
=== 0.4.2
|
280
|
+
|
281
|
+
* Fixed bug in parallel edge adjacency detection.
|
282
|
+
* Fix to allow symbols to be passed through to dot for labels.
|
283
|
+
* Changed naming to use Arcs for Digraphs and Edges for Undirected Graphs.
|
284
|
+
* Added a gem release.
|
285
|
+
|
286
|
+
=== 0.4.1
|
287
|
+
|
288
|
+
* Got reflection working for graphs
|
289
|
+
* Fixed major bugs in multi and pseudo graph handling
|
290
|
+
|
291
|
+
=== 0.4.0
|
292
|
+
|
293
|
+
Initial release of fork from RGL library.
|
294
|
+
|
295
|
+
== Copying
|
296
|
+
|
297
|
+
Copyright (c) 2006 Shawn Patrick Garbett
|
298
|
+
|
299
|
+
Copyright (c) 2002,2004,2005 by Horst Duchene
|
300
|
+
|
301
|
+
Copyright (c) 2000,2001 Jeremy Siek, Indiana University (jsiek@osl.iu.edu)
|
302
|
+
|
303
|
+
All rights reserved.
|
304
|
+
|
305
|
+
Jeremy Siek was one of the principal developers of the Boost Graph library.
|
306
|
+
Since this work is derivative, his name is included in the copyright list.
|
307
|
+
|
308
|
+
Redistribution and use in source and binary forms, with or without modification,
|
309
|
+
are permitted provided that the following conditions are met:
|
310
|
+
|
311
|
+
* Redistributions of source code must retain the above copyright notice(s),
|
312
|
+
this list of conditions and the following disclaimer.
|
313
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
314
|
+
this list of conditions and the following disclaimer in the documentation
|
315
|
+
and/or other materials provided with the distribution.
|
316
|
+
* Neither the name of the Shawn Garbett nor the names of its contributors
|
317
|
+
may be used to endorse or promote products derived from this software
|
318
|
+
without specific prior written permission.
|
319
|
+
|
320
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
321
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
322
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
323
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
324
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
325
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
326
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
327
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
328
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
329
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
330
|
+
|
331
|
+
== Support
|
332
|
+
|
333
|
+
Please contact me at mailto:shawn@garbett.org with bug reports
|
334
|
+
suggestions, and other comments. If you send patches, it would help if
|
335
|
+
they were generated using "diff -u".
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/ruby -I../lib
|
2
|
+
|
3
|
+
require 'gratr/import'
|
4
|
+
require 'gratr/dot'
|
5
|
+
|
6
|
+
# This program gives an example of dynamic analysis of a program's call stack,
|
7
|
+
# that exports to dot and creates a jpg visualization of the call diagram.
|
8
|
+
|
9
|
+
class GraphSelf
|
10
|
+
|
11
|
+
# Setup some data to call Dijkstra's Algorithm
|
12
|
+
def initialize
|
13
|
+
@d = Digraph[ [:a,:b] => 9, [:a,:e] => 3,
|
14
|
+
[:b,:c] => 2, [:b,:e] => 6,
|
15
|
+
[:c,:d] => 1,
|
16
|
+
[:d,:c] => 2,
|
17
|
+
[:e,:b] => 2, [:e,:f] => 1,
|
18
|
+
[:f,:c] => 2, [:f,:d] => 7, [:f,:e] => 2 ]
|
19
|
+
|
20
|
+
@call_stack = []
|
21
|
+
@call_graph = Digraph.new
|
22
|
+
end
|
23
|
+
|
24
|
+
# Get the call graph variable
|
25
|
+
def call_graph() @call_graph; end
|
26
|
+
|
27
|
+
# Turn capturing of call graph on
|
28
|
+
def capture_func
|
29
|
+
Proc.new do |event, f, l, id, b, klass|
|
30
|
+
# Only interested in the GRATR library itself
|
31
|
+
if ( klass.to_s =~ /GRATR/ )
|
32
|
+
case event.to_s
|
33
|
+
when /call/
|
34
|
+
method = "#{klass.to_s.split('::')[1]}.#{id}" # Removes GRATR::
|
35
|
+
@call_graph.add_edge!(@call_stack[-1],method) if @call_stack[-1]
|
36
|
+
@call_stack.push(method)
|
37
|
+
when /return/ : @call_stack.pop
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Run a capture of the call graph for Dijkstra's algorithm
|
44
|
+
def run
|
45
|
+
set_trace_func capture_func
|
46
|
+
@d.dijkstras_algorithm(:a)
|
47
|
+
set_trace_func nil
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
# Run a capture and generate the resulting jpg file
|
54
|
+
GraphSelf.new.run.call_graph.write_to_graphic_file('jpg','self_graph')
|
Binary file
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/ruby -I../lib
|
2
|
+
|
3
|
+
require 'gratr/import'
|
4
|
+
require 'gratr/dot'
|
5
|
+
|
6
|
+
module_graph=Digraph.new
|
7
|
+
ObjectSpace.each_object(Module) do |m|
|
8
|
+
m.ancestors.each {|a| module_graph.add_edge!(m,a) if m != a}
|
9
|
+
end
|
10
|
+
|
11
|
+
gv = module_graph.vertices.select {|v| v.to_s.match(/GRATR/)}
|
12
|
+
module_graph.induced_subgraph(gv).write_to_graphic_file('jpg','module_graph')
|
Binary file
|
Binary file
|
data/install.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'getoptlong'
|
4
|
+
require 'rbconfig'
|
5
|
+
require 'ftools'
|
6
|
+
require 'find'
|
7
|
+
|
8
|
+
SRC_BASE = 'lib'
|
9
|
+
SRC = 'gratr'
|
10
|
+
|
11
|
+
|
12
|
+
INSTDIR = File.join Config::CONFIG['sitedir']
|
13
|
+
DESTDIR = File.join INSTDIR, SRC
|
14
|
+
|
15
|
+
opts = GetoptLong.new( [ "--uninstall", "-u", GetoptLong::NO_ARGUMENT ] )
|
16
|
+
|
17
|
+
def install
|
18
|
+
begin
|
19
|
+
File.makedirs( DESTDIR )
|
20
|
+
pwd = Dir.pwd
|
21
|
+
Dir.chdir(SRC_BASE)
|
22
|
+
Dir['*.rb'].each do |file|
|
23
|
+
dst = File.join( INSTDIR, file )
|
24
|
+
File.install(file, dst, 0644, true)
|
25
|
+
end
|
26
|
+
Find.find(SRC) do |file|
|
27
|
+
dst = File.join( INSTDIR, file )
|
28
|
+
File.install(file, dst, 0644, true) if file =~ /.rb$/
|
29
|
+
end
|
30
|
+
Dir.chdir(pwd)
|
31
|
+
rescue
|
32
|
+
puts $!
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def uninstall
|
37
|
+
begin
|
38
|
+
puts "Deleting:"
|
39
|
+
Find.find(DESTDIR) { |file| File.rm_f file,true }
|
40
|
+
Dir.delete DESTDIR
|
41
|
+
rescue
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
if (opt = opts.get) and opt[0] =~ /^-?-u/
|
46
|
+
uninstall
|
47
|
+
else
|
48
|
+
install
|
49
|
+
end
|