trimurti 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/trimurti-0.1/docs/classes/Array.html +176 -0
  2. data/trimurti-0.1/docs/classes/Array.src/M000005.html +19 -0
  3. data/trimurti-0.1/docs/classes/Array.src/M000006.html +19 -0
  4. data/trimurti-0.1/docs/classes/Asserter.html +136 -0
  5. data/trimurti-0.1/docs/classes/Brahma.html +360 -0
  6. data/trimurti-0.1/docs/classes/Brahma.src/M000029.html +21 -0
  7. data/trimurti-0.1/docs/classes/Brahma.src/M000030.html +20 -0
  8. data/trimurti-0.1/docs/classes/Brahma.src/M000031.html +36 -0
  9. data/trimurti-0.1/docs/classes/Brahma.src/M000032.html +18 -0
  10. data/trimurti-0.1/docs/classes/Brahma.src/M000033.html +20 -0
  11. data/trimurti-0.1/docs/classes/Brahma.src/M000034.html +21 -0
  12. data/trimurti-0.1/docs/classes/Brahma.src/M000035.html +25 -0
  13. data/trimurti-0.1/docs/classes/Brahma.src/M000036.html +22 -0
  14. data/trimurti-0.1/docs/classes/Brahma.src/M000037.html +22 -0
  15. data/trimurti-0.1/docs/classes/ComponentSpec.html +275 -0
  16. data/trimurti-0.1/docs/classes/ComponentSpec.src/M000001.html +21 -0
  17. data/trimurti-0.1/docs/classes/ComponentSpec.src/M000002.html +18 -0
  18. data/trimurti-0.1/docs/classes/DRb.html +165 -0
  19. data/trimurti-0.1/docs/classes/DRb.src/M000062.html +18 -0
  20. data/trimurti-0.1/docs/classes/DRb.src/M000063.html +18 -0
  21. data/trimurti-0.1/docs/classes/GUID.html +129 -0
  22. data/trimurti-0.1/docs/classes/Linda.html +444 -0
  23. data/trimurti-0.1/docs/classes/Linda.src/M000007.html +16 -0
  24. data/trimurti-0.1/docs/classes/Linda.src/M000008.html +16 -0
  25. data/trimurti-0.1/docs/classes/Linda.src/M000009.html +20 -0
  26. data/trimurti-0.1/docs/classes/Linda.src/M000010.html +16 -0
  27. data/trimurti-0.1/docs/classes/Linda.src/M000011.html +18 -0
  28. data/trimurti-0.1/docs/classes/Linda.src/M000012.html +21 -0
  29. data/trimurti-0.1/docs/classes/Linda.src/M000013.html +18 -0
  30. data/trimurti-0.1/docs/classes/Linda.src/M000014.html +18 -0
  31. data/trimurti-0.1/docs/classes/Linda.src/M000015.html +18 -0
  32. data/trimurti-0.1/docs/classes/Linda.src/M000016.html +18 -0
  33. data/trimurti-0.1/docs/classes/Linda.src/M000017.html +20 -0
  34. data/trimurti-0.1/docs/classes/Linda.src/M000018.html +20 -0
  35. data/trimurti-0.1/docs/classes/Object.html +153 -0
  36. data/trimurti-0.1/docs/classes/Object.src/M000021.html +18 -0
  37. data/trimurti-0.1/docs/classes/Plugins.html +174 -0
  38. data/trimurti-0.1/docs/classes/Plugins.src/M000024.html +32 -0
  39. data/trimurti-0.1/docs/classes/Plugins.src/M000025.html +32 -0
  40. data/trimurti-0.1/docs/classes/Plugins/Spec.html +267 -0
  41. data/trimurti-0.1/docs/classes/Plugins/Spec.src/M000026.html +22 -0
  42. data/trimurti-0.1/docs/classes/Plugins/Spec.src/M000027.html +18 -0
  43. data/trimurti-0.1/docs/classes/Plugins/Spec.src/M000028.html +20 -0
  44. data/trimurti-0.1/docs/classes/QBE_ID.html +147 -0
  45. data/trimurti-0.1/docs/classes/QBE_ID.src/M000059.html +18 -0
  46. data/trimurti-0.1/docs/classes/QueryByExample.html +270 -0
  47. data/trimurti-0.1/docs/classes/QueryByExample.src/M000054.html +17 -0
  48. data/trimurti-0.1/docs/classes/QueryByExample.src/M000055.html +17 -0
  49. data/trimurti-0.1/docs/classes/QueryByExample.src/M000056.html +17 -0
  50. data/trimurti-0.1/docs/classes/QueryByExample.src/M000057.html +17 -0
  51. data/trimurti-0.1/docs/classes/QueryByExample.src/M000058.html +17 -0
  52. data/trimurti-0.1/docs/classes/Shiva.html +159 -0
  53. data/trimurti-0.1/docs/classes/Shiva.src/M000060.html +18 -0
  54. data/trimurti-0.1/docs/classes/Shiva.src/M000061.html +19 -0
  55. data/trimurti-0.1/docs/classes/String.html +176 -0
  56. data/trimurti-0.1/docs/classes/String.src/M000022.html +16 -0
  57. data/trimurti-0.1/docs/classes/String.src/M000023.html +16 -0
  58. data/trimurti-0.1/docs/classes/Symbol.html +176 -0
  59. data/trimurti-0.1/docs/classes/Symbol.src/M000003.html +16 -0
  60. data/trimurti-0.1/docs/classes/Symbol.src/M000004.html +16 -0
  61. data/trimurti-0.1/docs/classes/Trimurti.html +189 -0
  62. data/trimurti-0.1/docs/classes/Trimurti.src/M000019.html +16 -0
  63. data/trimurti-0.1/docs/classes/Trimurti.src/M000020.html +16 -0
  64. data/trimurti-0.1/docs/classes/Vishnu.html +563 -0
  65. data/trimurti-0.1/docs/classes/Vishnu.src/M000038.html +18 -0
  66. data/trimurti-0.1/docs/classes/Vishnu.src/M000039.html +18 -0
  67. data/trimurti-0.1/docs/classes/Vishnu.src/M000040.html +18 -0
  68. data/trimurti-0.1/docs/classes/Vishnu.src/M000041.html +22 -0
  69. data/trimurti-0.1/docs/classes/Vishnu.src/M000042.html +23 -0
  70. data/trimurti-0.1/docs/classes/Vishnu.src/M000043.html +24 -0
  71. data/trimurti-0.1/docs/classes/Vishnu.src/M000044.html +24 -0
  72. data/trimurti-0.1/docs/classes/Vishnu.src/M000045.html +18 -0
  73. data/trimurti-0.1/docs/classes/Vishnu.src/M000046.html +22 -0
  74. data/trimurti-0.1/docs/classes/Vishnu.src/M000047.html +20 -0
  75. data/trimurti-0.1/docs/classes/Vishnu.src/M000048.html +18 -0
  76. data/trimurti-0.1/docs/classes/Vishnu.src/M000049.html +22 -0
  77. data/trimurti-0.1/docs/classes/Vishnu.src/M000050.html +20 -0
  78. data/trimurti-0.1/docs/classes/Vishnu.src/M000051.html +19 -0
  79. data/trimurti-0.1/docs/classes/Vishnu.src/M000052.html +30 -0
  80. data/trimurti-0.1/docs/classes/Vishnu.src/M000053.html +21 -0
  81. data/trimurti-0.1/docs/created.rid +1 -0
  82. data/trimurti-0.1/docs/dot/f_0.dot +14 -0
  83. data/trimurti-0.1/docs/dot/f_0.png +0 -0
  84. data/trimurti-0.1/docs/dot/f_1.dot +14 -0
  85. data/trimurti-0.1/docs/dot/f_1.png +0 -0
  86. data/trimurti-0.1/docs/dot/f_2.dot +14 -0
  87. data/trimurti-0.1/docs/dot/f_2.png +0 -0
  88. data/trimurti-0.1/docs/dot/f_3.dot +39 -0
  89. data/trimurti-0.1/docs/dot/f_3.png +0 -0
  90. data/trimurti-0.1/docs/dot/f_4.dot +39 -0
  91. data/trimurti-0.1/docs/dot/f_4.png +0 -0
  92. data/trimurti-0.1/docs/dot/f_5.dot +69 -0
  93. data/trimurti-0.1/docs/dot/f_5.png +0 -0
  94. data/trimurti-0.1/docs/dot/f_6.dot +149 -0
  95. data/trimurti-0.1/docs/dot/f_6.png +0 -0
  96. data/trimurti-0.1/docs/dot/m_3_0.dot +30 -0
  97. data/trimurti-0.1/docs/dot/m_3_0.png +0 -0
  98. data/trimurti-0.1/docs/dot/m_4_0.dot +39 -0
  99. data/trimurti-0.1/docs/dot/m_4_0.png +0 -0
  100. data/trimurti-0.1/docs/dot/m_5_0.dot +40 -0
  101. data/trimurti-0.1/docs/dot/m_5_0.png +0 -0
  102. data/trimurti-0.1/docs/dot/m_5_1.dot +30 -0
  103. data/trimurti-0.1/docs/dot/m_5_1.png +0 -0
  104. data/trimurti-0.1/docs/dot/m_6_0.dot +40 -0
  105. data/trimurti-0.1/docs/dot/m_6_0.png +0 -0
  106. data/trimurti-0.1/docs/dot/m_6_1.dot +30 -0
  107. data/trimurti-0.1/docs/dot/m_6_1.png +0 -0
  108. data/trimurti-0.1/docs/dot/m_6_2.dot +30 -0
  109. data/trimurti-0.1/docs/dot/m_6_2.png +0 -0
  110. data/trimurti-0.1/docs/files/License_txt.html +132 -0
  111. data/trimurti-0.1/docs/files/ReadMe_Amber_txt.html +491 -0
  112. data/trimurti-0.1/docs/files/ReadMe_txt.html +694 -0
  113. data/trimurti-0.1/docs/files/nist/trimurti/linda_rb.html +129 -0
  114. data/trimurti-0.1/docs/files/nist/trimurti/plugins_rb.html +129 -0
  115. data/trimurti-0.1/docs/files/nist/trimurti/queryByExample_rb.html +128 -0
  116. data/trimurti-0.1/docs/files/nist/trimurti/trimurti_rb.html +151 -0
  117. data/trimurti-0.1/docs/fr_class_index.html +43 -0
  118. data/trimurti-0.1/docs/fr_file_index.html +33 -0
  119. data/trimurti-0.1/docs/fr_method_index.html +89 -0
  120. data/trimurti-0.1/docs/images/overview.jpg +0 -0
  121. data/trimurti-0.1/docs/index.html +24 -0
  122. data/trimurti-0.1/docs/rdoc-style.css +208 -0
  123. data/trimurti-0.1/lib/nist/trimurti/linda.rb +163 -0
  124. data/trimurti-0.1/lib/nist/trimurti/plugins.rb +107 -0
  125. data/trimurti-0.1/lib/nist/trimurti/queryByExample.rb +81 -0
  126. data/trimurti-0.1/lib/nist/trimurti/trimurti.rb +433 -0
  127. data/trimurti-0.1/tests/test_linda.rb +111 -0
  128. data/trimurti-0.1/tests/test_trimurti.rb +247 -0
  129. metadata +241 -0
@@ -0,0 +1,694 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>File: ReadMe.txt</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="fileHeader">
50
+ <h1>ReadMe.txt</h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>Path:</strong></td>
54
+ <td>ReadMe.txt
55
+ </td>
56
+ </tr>
57
+ <tr class="top-aligned-row">
58
+ <td><strong>Last Update:</strong></td>
59
+ <td>Sun Jan 15 15:10:20 EST 2006</td>
60
+ </tr>
61
+ </table>
62
+ </div>
63
+ <!-- banner header -->
64
+
65
+ <div id="bodyContent">
66
+
67
+
68
+
69
+ <div id="contextContent">
70
+ <div id="diagram">
71
+ <map id="map" name="map">
72
+ </map>
73
+ <img src="../dot/f_1.png" usemap="#map" border=0 alt="TopLevel">
74
+ </div>
75
+
76
+ <div id="description">
77
+ <h2>Overview</h2>
78
+ <p>
79
+ <a href="../classes/Trimurti.html">Trimurti</a> simplifies the assembly of
80
+ modularized applications.
81
+ </p>
82
+ <p>
83
+ Included is code to:
84
+ </p>
85
+ <ul>
86
+ <li>Search for plugin code resident on the host running the application
87
+
88
+ </li>
89
+ <li>Load plugins
90
+
91
+ </li>
92
+ <li>Keep track of local and distributed components and services
93
+
94
+ </li>
95
+ <li>Connect consumers to local and distributed services
96
+
97
+ </li>
98
+ <li>Configure the relationships between service consumers and providers
99
+
100
+ </li>
101
+ <li>Tear down the application when it&#8217;s finished
102
+
103
+ </li>
104
+ </ul>
105
+ <p>
106
+ Some of this functionality is known &quot;Dependency Injection&quot;, or
107
+ &quot;Inversion of Control&quot;. These ideas are described at <a
108
+ href="http://www.martinfowler.com/articles/injection.html">www.martinfowler.com/articles/injection.html</a>.
109
+ </p>
110
+ <h3>Analysis Class Model</h3>
111
+ <p>
112
+ <img src="../images/overview.jpg">
113
+ </p>
114
+ <h3>Discsussion of Class Model</h3>
115
+ <p>
116
+ Starting in the lower right corner of the diagram, a Plugin is a File
117
+ containing arbitrary Code and/or Components. If the application loads the
118
+ plugins after all other code has been required, the plugins can add
119
+ functionality to any class in the application.
120
+ </p>
121
+ <p>
122
+ Components are Objects that provide one or more Services to other Objects
123
+ in the system. A Service is an API designated by a <a
124
+ href="../classes/Symbol.html">Symbol</a>. Depending on the configuration
125
+ (which will be discussed momentarily), Components may either
126
+ </p>
127
+ <ul>
128
+ <li>Require services provided by any any object that implements the designated
129
+ API,
130
+
131
+ </li>
132
+ <li>Require services provided by some specific Component (identified by name).
133
+
134
+ </li>
135
+ </ul>
136
+ <p>
137
+ Components can be assembled automatically by an instance of any class that
138
+ mixes in <a href="../classes/Brahma.html">Brahma</a>. To participate in
139
+ automatic assembly, Components need to be registered with the assembler.
140
+ You can mix <a href="../classes/Brahma.html">Brahma</a> into your own
141
+ class, or use <a href="../classes/Trimurti.html">Trimurti</a>. If you use
142
+ <a href="../classes/Trimurti.html">Trimurti</a>, You can either create one
143
+ or more instances of <a href="../classes/Trimurti.html">Trimurti</a> (being
144
+ aware that they will have different registries), or you can send messages
145
+ to the class (they will be redirected to a default instance). The rdocs do
146
+ not show these redirected messages, because they are metacoded (which is
147
+ invisible to rdoc).
148
+ </p>
149
+ <p>
150
+ There are two ways to register components:
151
+ </p>
152
+ <ul>
153
+ <li>register_component can be called from a &#8216;require&#8217;d file, such
154
+ as a plugin. This method allow the loosest coupling, since no configuration
155
+ file is required.
156
+
157
+ </li>
158
+ <li>application setup code can use <a
159
+ href="../classes/Brahma.html#M000035">Brahma#from_yaml</a> to parse a YAML
160
+ file that contains marshalled ComponentSpecs.
161
+
162
+ </li>
163
+ </ul>
164
+ <p>
165
+ Once all the Components have been registered, the <a
166
+ href="../classes/Brahma.html#M000033">Brahma#assemble</a> method perfoms
167
+ the assembly.
168
+ </p>
169
+ <p>
170
+ To assemble the Components into larger structures, Brama calls setters. The
171
+ registration information must include a setter method name for every
172
+ Service that a Component requires.
173
+ </p>
174
+ <p>
175
+ Components can also have code snippets for each of several life cyle
176
+ events. Although the application can specify additional life cycle events,
177
+ the standard selectors are:
178
+ </p>
179
+ <ul>
180
+ <li>:create - Instantiate the component
181
+
182
+ </li>
183
+ <li>:start - Activate the component&#8217;s services
184
+
185
+ </li>
186
+ <li>:stop - Turn off the component&#8217;s services
187
+
188
+ </li>
189
+ <li>:destroy - Discard references to other components
190
+
191
+ </li>
192
+ </ul>
193
+ <p>
194
+ These code snippets are Strings that are executed in the context of the
195
+ object that performs the assembly. To execute behaviors in the Component,
196
+ send messages to the &#8216;component&#8217; local variable:
197
+ </p>
198
+ <pre>
199
+ {:start =&gt; 'component.do_startup_stuff'}
200
+ </pre>
201
+ <p>
202
+ Notice that the &#8216;component&#8217; local variable is nil during
203
+ :create snippet execution. All of the life cycle snippets are optional,
204
+ except for :create, which is required
205
+ </p>
206
+ <ul>
207
+ <li>when registration is through marshalled ComponentSpecs
208
+
209
+ </li>
210
+ <li>when register_component is given a nil component to register.
211
+
212
+ </li>
213
+ </ul>
214
+ <p>
215
+ When the application is ready to quit, <a
216
+ href="../classes/Shiva.html#M000061">Shiva#destroy_components</a> can be
217
+ called to invoke any Component optional :stop and/or :destroy life_cycle
218
+ code.
219
+ </p>
220
+ <p>
221
+ If you wish to add your own life_cycle events, you need to call the
222
+ life_cycle method to trigger execution of the specified snippet for all the
223
+ Components that have been registered with with that event. The order is not
224
+ specified. For example, if
225
+ </p>
226
+ <pre>
227
+ {:lunar_eclipse =&gt; 'component.mysterious_stuff'}
228
+ </pre>
229
+ <p>
230
+ is included in a Component&#8217;s life_cycle Hash, that Component will
231
+ perform its mysterious_stuff behavior when the application invokes
232
+ </p>
233
+ <pre>
234
+ Trimurti.life_cycle(:lunar_eclipse)
235
+ </pre>
236
+ <p>
237
+ (provided, of course, the default <a
238
+ href="../classes/Trimurti.html">Trimurti</a> instance was used to assemble
239
+ all the Components).
240
+ </p>
241
+ <h2>Status</h2>
242
+ <p>
243
+ <a href="../classes/Trimurti.html">Trimurti</a> is currently pre-release
244
+ software, which has not yet undergone internal reviews. <a
245
+ href="../classes/Trimurti.html">Trimurti</a> is actively being used on the
246
+ large Focus project to build an augmented reality UML modeling tool.
247
+ </p>
248
+ <h2>Installation</h2>
249
+ <p>
250
+ <a href="../classes/Trimurti.html">Trimurti</a> can be downloaded in
251
+ several forms:
252
+ </p>
253
+ <ul>
254
+ <li>A RubyGem, containing only <a href="../classes/Trimurti.html">Trimurti</a>.
255
+ Due to lack of resources, the RubyGem is untested.
256
+
257
+ </li>
258
+ <li>A development snapshot containing <a
259
+ href="../classes/Trimurti.html">Trimurti</a> and nearly everything it
260
+ depends on, in a .tgz or .zip archive. The shapshot contains a complete
261
+ Amber development environment. Before using the development snapshot, you
262
+ need to:
263
+
264
+ <ol>
265
+ <li>Setup Amber (included in the snapshot): see <a
266
+ href="ReadMe_Amber_txt.html">ReadMe_Amber.txt</a>
267
+
268
+ </li>
269
+ <li>Install libraries required by <a
270
+ href="../classes/Trimurti.html">Trimurti</a>:
271
+
272
+ <pre>
273
+ cd $DevRoot/Projects/trimurti
274
+ rake install_lib
275
+ </pre>
276
+ </li>
277
+ </ol>
278
+ </li>
279
+ </ul>
280
+ <h2><a href="../classes/Plugins.html">Plugins</a></h2>
281
+ <p>
282
+ <a href="../classes/Plugins.html">Plugins</a> are files that can be loaded
283
+ by Ruby&#8217;s &quot;require&quot; method. <a
284
+ href="../classes/Plugins.html">Plugins</a> reside on the
285
+ application&#8217;s host: they may or may not offer or use components or
286
+ services.
287
+ </p>
288
+ <p>
289
+ Plugin handling code can be mixed into any class. There are several ways
290
+ applications can use this code. In every case the application loads plugins
291
+ via require_plugins, but there are different ways to integrate the plugin
292
+ into the application. The plugin needs to know which integration methods
293
+ are supported by the application.
294
+ </p>
295
+ <p>
296
+ Integration of the plugins into the application may require:
297
+ </p>
298
+ <ul>
299
+ <li>Initializing any data structures required by the plugin
300
+
301
+ </li>
302
+ <li>Adding the plugin&#8217;s functionality to the application&#8217;s menus
303
+
304
+ </li>
305
+ <li>Adding a description of the Plugin to the appliction&#8217;s
306
+ &quot;About&#8230;&quot; dialog.
307
+
308
+ </li>
309
+ </ul>
310
+ <p>
311
+ The following methods can be used to integrate plugins:
312
+ </p>
313
+ <ul>
314
+ <li>The plugin code can add a <a
315
+ href="../classes/Plugins/Spec.html">Plugins::Spec</a> object to $PLUGINS.
316
+ The application can then use this information to integrate the plugins (see
317
+ the upcoming example)
318
+
319
+ </li>
320
+ <li>The application can supply a block to require_plugins, which takes as an
321
+ argument the plugin file&#8217;s local path (with file name but without
322
+ extension). This block is executed after the plugin is loaded. The block
323
+ can invoke application-required plugin-specific integration code which is
324
+ defined in the plugin itself.
325
+
326
+ </li>
327
+ <li>The plugin can add methods to the application, and change methods in the
328
+ application, so that it behaves differently.
329
+
330
+ </li>
331
+ <li><a href="../classes/Plugins.html">Plugins</a> can contain components and
332
+ services which can be hooked up automatically by <a
333
+ href="../classes/Brahma.html">Brahma</a>.
334
+
335
+ </li>
336
+ </ul>
337
+ <h2>Using plugins (presuming integration via $PLUGINS)</h2>
338
+ <h3>Application code</h3>
339
+ <pre>
340
+ require 'nist/trimurti/plugins'
341
+
342
+ class SomeApplication
343
+ include 'Plugins'
344
+ def run
345
+ require_plugins('some/path/*.rb')
346
+ $PLUGINS.each {|plugin_spec|
347
+ plugin_spec.init(self)
348
+ next unless app_has_gui
349
+ # Add here: your code that integrates plugin_spec.actions into GUI.
350
+ # The following example plugin code presumes menus call Procs.
351
+ # Add here: your code that adds plugin_spec.to_s into the &quot;About...&quot; dialog
352
+ }
353
+ # Add here: your non-plugin runtime behavior
354
+ end
355
+
356
+ SomeApplication.new.run
357
+ </pre>
358
+ <h3>Plugin code</h3>
359
+ <pre>
360
+ class SomeApplication
361
+ def fly
362
+ # some code
363
+ end
364
+ def crash_land
365
+ # more code
366
+ end
367
+ def fuelup
368
+ # initialize flying capability
369
+ end
370
+ end
371
+
372
+ # Adds 'PixieDust' functionality to SomeApplication. The author is 'Wile E. Coyote'
373
+ spec = Plugins::Spec.new('PixieDust', 'Wile E. Coyote', 'Makes application fly')
374
+ spec.init_proc = lamba {|app| app.fuelup }
375
+ spec.actions = { 'Fly' =&gt; lambda {|app| app.fly}, 'Crash' =&gt; lambda {|app| app.crash_land} }
376
+
377
+ $PLUGINS &lt;&lt; spec
378
+ # We are presuming that SomeApplication (in it's startup code)
379
+ # 1. Requires the plugin code
380
+ # 2. Iterates over $PLUGINS, to add 'Fly' and 'Crash' menu items to a Plugin menu.
381
+ </pre>
382
+ <h2><a href="../classes/Linda.html">Linda</a></h2>
383
+ <p>
384
+ <a href="../classes/Linda.html">Linda</a> is a wrapper on Rinda that makes
385
+ it look a bit more like the <a href="../classes/Linda.html">Linda</a>
386
+ described by Carriero and Gelernter, and that makes it easier to switch
387
+ between local and distributed Tuple spaces. Unlike Rinda, <a
388
+ href="../classes/Linda.html">Linda</a> Tuples do not expire. <a
389
+ href="../classes/Linda.html">Linda</a> does not yet accomodate
390
+ &#8216;live&#8217; (in Gelernter&#8217;s sense, meaning
391
+ &#8216;executing&#8217;) Tuples (which are not part of Rinda). You do not
392
+ need to understand or use <a href="../classes/Linda.html">Linda</a> in
393
+ order to use plugins, components, or services, but it&#8217;s available if
394
+ you want it.
395
+ </p>
396
+ <h2>Using <a href="../classes/Linda.html">Linda</a></h2>
397
+ <pre>
398
+ require 'nist/trimurti/linda'
399
+
400
+ # Insert some Tuples in Tuplespace
401
+ Linda.put(:superhero, 'Flaming Carrot', 'Zen Stupidity')
402
+ Linda.put(:superhero, 'The Spleen', 'Flatulence')
403
+ Linda.put(:vegetable, 'Carrot', 'Beta carotene')
404
+
405
+ # Prints &quot;[:vegetable, 'Carrot', 'Beta carotene']&quot; (rdp reads Tuple: if no match, it returns nil)
406
+ print &quot;\n#{Linda.rdp(:vegetable, /Carrot/, nil).inspect}&quot;
407
+
408
+ # Prints 'nil'
409
+ print &quot;\n#{Linda.rdp(:vegetable, /Wombat/, nil).inspect}&quot;
410
+
411
+ # Prints &quot;[ [:superhero, 'Flaming Carrot', 'Zen Stupidity'], [:vegetable, 'Carrot', 'Beta carotene'] ]&quot;
412
+ print &quot;\n#{Linda.rd_all(nil, /Carrot/, nil).inspect}&quot;
413
+
414
+ # Prints '[]'
415
+ print &quot;\n#{Linda.rd_all(nil, /Wombat/, nil).inspect}&quot;
416
+
417
+ # Prints &quot;[:superhero, 'Flaming Carrot', 'Zen Stupidity']&quot; (removes Tuple: if no match, sleeps until one is available)
418
+ print &quot;\n#{Linda.get(:superhero, /Carrot/, nil).inspect}&quot;
419
+
420
+ # Prints 'nil' (because we removed the tuple)
421
+ print &quot;\n#{Linda.rdp(:superhero, /Carrot/, nil).inspect}&quot;
422
+ </pre>
423
+ <h2>Components and Services</h2>
424
+ <p>
425
+ A service is a coherent collection of behaviors offered by a local or
426
+ remote object. A component is an object that consumes and/or offers one or
427
+ more services. Components are typically loaded via require_plugins.
428
+ </p>
429
+ <p>
430
+ Several modules are available for managing components and services:
431
+ </p>
432
+ <ul>
433
+ <li><a href="../classes/Vishnu.html">Vishnu</a> uses <a
434
+ href="../classes/Linda.html">Linda</a> to preserve registries of Components
435
+ and Services.
436
+
437
+ </li>
438
+ <li><a href="../classes/Brahma.html">Brahma</a> uses the component and service
439
+ registries to create applications by automatically interconnecting
440
+ components and services.
441
+
442
+ </li>
443
+ <li><a href="../classes/Shiva.html">Shiva</a> uses the component registry to
444
+ shutdown and destroy applications in an orderly fashion.
445
+
446
+ </li>
447
+ </ul>
448
+ <p>
449
+ <a href="../classes/Trimurti.html">Trimurti</a> is a class that includes
450
+ all the plugin, component, and service managment functionality.
451
+ </p>
452
+ <p>
453
+ Tuples in the component registry look like this:
454
+ </p>
455
+ <pre>
456
+ [:component, name, component, hostname, provides, needs, life_cycle]
457
+ </pre>
458
+ <ol>
459
+ <li>:component is a literal, shared by all components.
460
+
461
+ </li>
462
+ <li>&#8216;name&#8217; is a <a href="../classes/String.html">String</a> which
463
+ uniqely identifies the component
464
+
465
+ </li>
466
+ <li>&#8216;component&#8217; is the object providing the service (or a DRB
467
+ proxy)
468
+
469
+ </li>
470
+ <li>&#8216;hostname&#8217; is <a href="../classes/String.html">String</a> that
471
+ identifies the computer providing the component
472
+
473
+ </li>
474
+ <li>&#8216;provides&#8217; is an <a href="../classes/Array.html">Array</a> of
475
+ Symbols: each is the name of a service API served up by the component.
476
+ Typically the API is a module, but it does not have to be: it can just be a
477
+ symbolic name for a collection of methods.
478
+
479
+ </li>
480
+ <li>&#8216;needs&#8217; is a Hash that describes how to provide necessary
481
+ services to the component:
482
+
483
+ <ul>
484
+ <li>Key is a name of a method (on the component) that takes one argument (the
485
+ service provider)
486
+
487
+ </li>
488
+ <li>Value is either:
489
+
490
+ <ul>
491
+ <li>a <a href="../classes/Symbol.html">Symbol</a> that identifies the required
492
+ API
493
+
494
+ </li>
495
+ <li>an <a href="../classes/Array.html">Array</a> containing the 3 arguments to
496
+ :service
497
+
498
+ </li>
499
+ </ul>
500
+ </li>
501
+ </ul>
502
+ </li>
503
+ <li>&#8216;life_cycle&#8217; is a Hash the describes how to manage the
504
+ component:
505
+
506
+ <ul>
507
+ <li>Keys are Symbols that specify life cycle events. The following keys are
508
+ valid:
509
+
510
+ <ul>
511
+ <li>:create - Instantiate the component
512
+
513
+ </li>
514
+ <li>:start - Activate all services (called after connection to other services)
515
+
516
+ </li>
517
+ <li>:stop - Turn off all services (called before destruction)
518
+
519
+ </li>
520
+ <li>:destroy - Discard references to other components
521
+
522
+ </li>
523
+ </ul>
524
+ </li>
525
+ <li>Values are code Strings that specify behaviors that is to occur at life
526
+ cyle events.
527
+
528
+ </li>
529
+ </ul>
530
+ </li>
531
+ </ol>
532
+ <p>
533
+ Tuples in the service registry look like this:
534
+ </p>
535
+ <pre>
536
+ [:service, name, component, hostname, symbol]
537
+ </pre>
538
+ <ol>
539
+ <li>:service is a literal, shared by all services.
540
+
541
+ </li>
542
+ <li>&#8216;name&#8217; is a <a href="../classes/String.html">String</a> which
543
+ uniqely identifies the component providing the service
544
+
545
+ </li>
546
+ <li>&#8216;component&#8217; is the component object providing the service
547
+
548
+ </li>
549
+ <li>&#8216;hostname&#8217; is <a href="../classes/String.html">String</a> that
550
+ identifies the computer providing the service
551
+
552
+ </li>
553
+ <li>&#8216;symbol&#8217; specifies the service API served up by the component.
554
+ Of course a given component may offer more than one service API: if it
555
+ does,
556
+
557
+ <pre>
558
+ that component has multiple :service Tuples, one for each service it offers.
559
+ </pre>
560
+ </li>
561
+ </ol>
562
+ <p>
563
+ Service tuples can be generated automatically from the component tuples:
564
+ one component Tuple may correspond to several service Tuples.
565
+ </p>
566
+ <p>
567
+ The application needs to:
568
+ </p>
569
+ <ol>
570
+ <li>Register Components, either via:
571
+
572
+ <ul>
573
+ <li>from_yaml (in the application)
574
+
575
+ </li>
576
+ <li>register_component (in the plugins)
577
+
578
+ </li>
579
+ </ul>
580
+ </li>
581
+ <li>Interconnect the components, via assemble
582
+
583
+ </li>
584
+ </ol>
585
+ <h2>Using Components and Services (application expects plugins to register components)</h2>
586
+ <h3>Application code</h3>
587
+ <pre>
588
+ require 'nist/trimurti/trimurti'
589
+
590
+ class SomeApplication
591
+ def run
592
+ Trimurti.require_plugins('my/path/*.rb')
593
+ # Presumes plugin code registers components.
594
+ # If plugins do not register components, the
595
+ # application could use Trimurti.from_yaml to register components
596
+ Trimurti.assemble
597
+ # Application specific code
598
+ # Add here: other runtime behavior
599
+ #
600
+ # Once the application is finished:
601
+ Trimurti.destroy_components
602
+ end
603
+ end
604
+
605
+ SomeApplication.new.run
606
+ </pre>
607
+ <h3>Plugin code</h3>
608
+ <pre>
609
+ class SomeServer
610
+ include InterfaceX
611
+ include InterfaceY
612
+ attr_accessor :trouble
613
+ def start
614
+ # listen for requests included in InterfaceX and InterfaceY
615
+ end
616
+ end
617
+
618
+ server = SomeServer.new
619
+
620
+ # Presumes another Component in a different plugin implments :Trouble
621
+ Trimurti.register_component('Wolfgang', server, [:InterfaceX, :InterfaceY], {:trouble= =&gt; :Trouble})
622
+
623
+ server.start
624
+ </pre>
625
+ <h2>Alternatives</h2>
626
+ <p>
627
+ Ruby dependency injection possibilites include:
628
+ </p>
629
+ <ul>
630
+ <li>Needle <a href="http://needle.rubyforge.org">needle.rubyforge.org</a>/
631
+
632
+ </li>
633
+ <li>Seep <a href="http://seep.rubyforge.org">seep.rubyforge.org</a>/
634
+
635
+ </li>
636
+ <li>Copland <a href="http://copland.rubyforge.org">copland.rubyforge.org</a>/
637
+
638
+ </li>
639
+ <li>MinDI <a
640
+ href="http://redshift.sourceforge.net/mindi/doc/index.html">redshift.sourceforge.net/mindi/doc/index.html</a>
641
+
642
+ </li>
643
+ <li>Rico <a
644
+ href="http://raa.ruby-lang.org/project/rico">raa.ruby-lang.org/project/rico</a>/
645
+
646
+ </li>
647
+ </ul>
648
+ <h2>Room for improvement</h2>
649
+ <ul>
650
+ <li>Some security mechanism should be added for ComponentSpec.life_cycle code
651
+ Strings and Plugins::Spec.init_proc
652
+
653
+ </li>
654
+ <li>life_cycle and init_proc could be made to accept the developer&#8217;s
655
+ choice of Procs, Symbols, or Strings for customization.
656
+
657
+ </li>
658
+ </ul>
659
+ <p>
660
+ Author: A. Griesser
661
+ </p>
662
+
663
+ </div>
664
+
665
+
666
+ </div>
667
+
668
+
669
+ </div>
670
+
671
+
672
+ <!-- if includes -->
673
+
674
+ <div id="section">
675
+
676
+
677
+
678
+
679
+
680
+
681
+
682
+
683
+ <!-- if method_list -->
684
+
685
+
686
+ </div>
687
+
688
+
689
+ <div id="validator-badges">
690
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
691
+ </div>
692
+
693
+ </body>
694
+ </html>