wurlinc-rice 1.4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. data/COPYING +23 -0
  2. data/Doxyfile +1253 -0
  3. data/Makefile.am +26 -0
  4. data/README +1119 -0
  5. data/README.mingw +8 -0
  6. data/Rakefile +33 -0
  7. data/bootstrap +9 -0
  8. data/configure.ac +52 -0
  9. data/doxygen.ac +314 -0
  10. data/doxygen.am +186 -0
  11. data/extconf.rb +41 -0
  12. data/post-autoconf.rb +22 -0
  13. data/post-automake.rb +28 -0
  14. data/rice/Address_Registration_Guard.hpp +7 -0
  15. data/rice/Address_Registration_Guard.ipp +34 -0
  16. data/rice/Address_Registration_Guard_defn.hpp +65 -0
  17. data/rice/Allocation_Strategies.hpp +37 -0
  18. data/rice/Arg.hpp +8 -0
  19. data/rice/Arg_impl.hpp +127 -0
  20. data/rice/Arg_operators.cpp +21 -0
  21. data/rice/Arg_operators.hpp +19 -0
  22. data/rice/Array.hpp +220 -0
  23. data/rice/Array.ipp +263 -0
  24. data/rice/Builtin_Object.hpp +8 -0
  25. data/rice/Builtin_Object.ipp +50 -0
  26. data/rice/Builtin_Object_defn.hpp +51 -0
  27. data/rice/Class.cpp +57 -0
  28. data/rice/Class.hpp +8 -0
  29. data/rice/Class.ipp +6 -0
  30. data/rice/Class_defn.hpp +83 -0
  31. data/rice/Constructor.hpp +367 -0
  32. data/rice/Critical_Guard.hpp +40 -0
  33. data/rice/Critical_Guard.ipp +26 -0
  34. data/rice/Data_Object.hpp +8 -0
  35. data/rice/Data_Object.ipp +133 -0
  36. data/rice/Data_Object_defn.hpp +132 -0
  37. data/rice/Data_Type.cpp +54 -0
  38. data/rice/Data_Type.hpp +8 -0
  39. data/rice/Data_Type.ipp +365 -0
  40. data/rice/Data_Type_defn.hpp +261 -0
  41. data/rice/Data_Type_fwd.hpp +12 -0
  42. data/rice/Director.cpp +13 -0
  43. data/rice/Director.hpp +39 -0
  44. data/rice/Enum.hpp +117 -0
  45. data/rice/Enum.ipp +246 -0
  46. data/rice/Exception.cpp +59 -0
  47. data/rice/Exception.hpp +9 -0
  48. data/rice/Exception_Base.hpp +8 -0
  49. data/rice/Exception_Base.ipp +13 -0
  50. data/rice/Exception_Base_defn.hpp +27 -0
  51. data/rice/Exception_defn.hpp +69 -0
  52. data/rice/Hash.hpp +210 -0
  53. data/rice/Hash.ipp +338 -0
  54. data/rice/Identifier.cpp +8 -0
  55. data/rice/Identifier.hpp +50 -0
  56. data/rice/Identifier.ipp +33 -0
  57. data/rice/Jump_Tag.hpp +24 -0
  58. data/rice/Makefile.am +129 -0
  59. data/rice/Module.cpp +84 -0
  60. data/rice/Module.hpp +8 -0
  61. data/rice/Module.ipp +6 -0
  62. data/rice/Module_defn.hpp +88 -0
  63. data/rice/Module_impl.hpp +281 -0
  64. data/rice/Module_impl.ipp +348 -0
  65. data/rice/Object.cpp +160 -0
  66. data/rice/Object.hpp +8 -0
  67. data/rice/Object.ipp +19 -0
  68. data/rice/Object_defn.hpp +191 -0
  69. data/rice/Require_Guard.hpp +21 -0
  70. data/rice/String.cpp +94 -0
  71. data/rice/String.hpp +89 -0
  72. data/rice/Struct.cpp +117 -0
  73. data/rice/Struct.hpp +162 -0
  74. data/rice/Struct.ipp +26 -0
  75. data/rice/Symbol.cpp +25 -0
  76. data/rice/Symbol.hpp +66 -0
  77. data/rice/Symbol.ipp +44 -0
  78. data/rice/VM.cpp +92 -0
  79. data/rice/VM.hpp +32 -0
  80. data/rice/config.hpp.in +40 -0
  81. data/rice/detail/Arguments.hpp +118 -0
  82. data/rice/detail/Auto_Function_Wrapper.hpp +829 -0
  83. data/rice/detail/Auto_Function_Wrapper.ipp +3391 -0
  84. data/rice/detail/Auto_Member_Function_Wrapper.hpp +828 -0
  85. data/rice/detail/Auto_Member_Function_Wrapper.ipp +2503 -0
  86. data/rice/detail/Caster.hpp +103 -0
  87. data/rice/detail/Exception_Handler.hpp +8 -0
  88. data/rice/detail/Exception_Handler.ipp +68 -0
  89. data/rice/detail/Exception_Handler_defn.hpp +96 -0
  90. data/rice/detail/Iterator.hpp +93 -0
  91. data/rice/detail/Not_Copyable.hpp +25 -0
  92. data/rice/detail/Wrapped_Function.hpp +33 -0
  93. data/rice/detail/cfp.hpp +24 -0
  94. data/rice/detail/cfp.ipp +51 -0
  95. data/rice/detail/check_ruby_type.cpp +27 -0
  96. data/rice/detail/check_ruby_type.hpp +23 -0
  97. data/rice/detail/creation_funcs.hpp +37 -0
  98. data/rice/detail/creation_funcs.ipp +36 -0
  99. data/rice/detail/default_allocation_func.hpp +23 -0
  100. data/rice/detail/default_allocation_func.ipp +11 -0
  101. data/rice/detail/define_method_and_auto_wrap.hpp +31 -0
  102. data/rice/detail/define_method_and_auto_wrap.ipp +30 -0
  103. data/rice/detail/demangle.cpp +56 -0
  104. data/rice/detail/demangle.hpp +19 -0
  105. data/rice/detail/env.hpp +19 -0
  106. data/rice/detail/from_ruby.hpp +43 -0
  107. data/rice/detail/from_ruby.ipp +60 -0
  108. data/rice/detail/method_data.cpp +159 -0
  109. data/rice/detail/method_data.hpp +21 -0
  110. data/rice/detail/mininode.cpp +1220 -0
  111. data/rice/detail/mininode.hpp +320 -0
  112. data/rice/detail/node.hpp +13 -0
  113. data/rice/detail/object_call.hpp +68 -0
  114. data/rice/detail/object_call.ipp +131 -0
  115. data/rice/detail/protect.cpp +29 -0
  116. data/rice/detail/protect.hpp +34 -0
  117. data/rice/detail/ruby.hpp +93 -0
  118. data/rice/detail/ruby_version_code.hpp.in +6 -0
  119. data/rice/detail/rubysig.hpp +19 -0
  120. data/rice/detail/st.hpp +60 -0
  121. data/rice/detail/to_ruby.hpp +22 -0
  122. data/rice/detail/to_ruby.ipp +36 -0
  123. data/rice/detail/traits.hpp +43 -0
  124. data/rice/detail/win32.hpp +16 -0
  125. data/rice/detail/wrap_function.hpp +341 -0
  126. data/rice/detail/wrap_function.ipp +514 -0
  127. data/rice/global_function.hpp +33 -0
  128. data/rice/global_function.ipp +22 -0
  129. data/rice/protect.hpp +91 -0
  130. data/rice/protect.ipp +1133 -0
  131. data/rice/ruby_mark.hpp +13 -0
  132. data/rice/ruby_try_catch.hpp +86 -0
  133. data/rice/rubypp.rb +97 -0
  134. data/rice/to_from_ruby.hpp +8 -0
  135. data/rice/to_from_ruby.ipp +297 -0
  136. data/rice/to_from_ruby_defn.hpp +71 -0
  137. data/ruby/Makefile.am +1 -0
  138. data/ruby/lib/Makefile.am +3 -0
  139. data/ruby/lib/mkmf-rice.rb.in +216 -0
  140. data/ruby/lib/version.rb +3 -0
  141. data/ruby.ac +136 -0
  142. data/sample/Makefile.am +47 -0
  143. data/sample/enum/extconf.rb +3 -0
  144. data/sample/enum/sample_enum.cpp +54 -0
  145. data/sample/enum/test.rb +8 -0
  146. data/sample/inheritance/animals.cpp +98 -0
  147. data/sample/inheritance/extconf.rb +3 -0
  148. data/sample/inheritance/test.rb +7 -0
  149. data/sample/map/extconf.rb +3 -0
  150. data/sample/map/map.cpp +81 -0
  151. data/sample/map/test.rb +7 -0
  152. data/test/Makefile.am +78 -0
  153. data/test/ext/Makefile.am +43 -0
  154. data/test/ext/t1/Foo.hpp +10 -0
  155. data/test/ext/t1/extconf.rb +2 -0
  156. data/test/ext/t1/t1.cpp +15 -0
  157. data/test/ext/t2/extconf.rb +2 -0
  158. data/test/ext/t2/t2.cpp +11 -0
  159. data/test/test_Address_Registration_Guard.cpp +43 -0
  160. data/test/test_Allocation_Strategies.cpp +77 -0
  161. data/test/test_Array.cpp +241 -0
  162. data/test/test_Builtin_Object.cpp +72 -0
  163. data/test/test_Class.cpp +498 -0
  164. data/test/test_Constructor.cpp +128 -0
  165. data/test/test_Critical_Guard.cpp +51 -0
  166. data/test/test_Data_Object.cpp +275 -0
  167. data/test/test_Data_Type.cpp +348 -0
  168. data/test/test_Director.cpp +301 -0
  169. data/test/test_Enum.cpp +195 -0
  170. data/test/test_Exception.cpp +46 -0
  171. data/test/test_Hash.cpp +195 -0
  172. data/test/test_Identifier.cpp +70 -0
  173. data/test/test_Jump_Tag.cpp +17 -0
  174. data/test/test_Memory_Management.cpp +50 -0
  175. data/test/test_Module.cpp +481 -0
  176. data/test/test_Object.cpp +148 -0
  177. data/test/test_String.cpp +94 -0
  178. data/test/test_Struct.cpp +192 -0
  179. data/test/test_Symbol.cpp +63 -0
  180. data/test/test_To_From_Ruby.cpp +263 -0
  181. data/test/test_VM.cpp +26 -0
  182. data/test/test_global_functions.cpp +114 -0
  183. data/test/test_rice.rb +43 -0
  184. data/test/unittest.cpp +136 -0
  185. data/test/unittest.hpp +292 -0
  186. metadata +276 -0
data/README ADDED
@@ -0,0 +1,1119 @@
1
+ \mainpage Rice - Ruby Interface for C++ Extensions
2
+
3
+
4
+ \section intro Introduction
5
+
6
+ Rice is a C++ interface to Ruby's C API. It provides a type-safe and
7
+ exception-safe interface in order to make embedding Ruby and writing
8
+ Ruby extensions with C++ easier. It is similar to Boost.Python in many
9
+ ways, but also attempts to provide an object-oriented interface to all
10
+ of the Ruby C API.
11
+
12
+ What Rice gives you:
13
+ \li A simple C++-based syntax for wrapping and defining classes
14
+ \li Automatic conversion of exceptions between C++ and Ruby
15
+ \li Smart pointers for handling garbage collection
16
+ \li Wrappers for most builtin types to simplify calling code
17
+
18
+ \section project Project Details
19
+
20
+ The source is hosted on github: http://github.com/jameskilton/rice
21
+
22
+ Bug tracking: http://github.com/jameskilton/rice/issues
23
+
24
+ Mailing List: rice@librelist.com (your first email will be used as a subscription request and dropped)
25
+
26
+ \section installation Installation
27
+
28
+ There are two ways to install Rice. You can download the tarball from the repository,
29
+ extract it and:
30
+
31
+ \code
32
+ ./configure
33
+ make
34
+ sudo make install
35
+ \endcode
36
+
37
+ or you can install via RubyGems
38
+
39
+ \code
40
+ gem install rice
41
+ \endcode
42
+
43
+ Note to Windows users: Rice is only known to properly compile and run under Cygwin and Mingw.
44
+
45
+ \section tutorial Tutorial
46
+
47
+ \subsection geting_started Getting started
48
+
49
+ Writing an extension with Rice is very similar to writing an extension
50
+ with the C API.
51
+
52
+ The first step is to create an extconf.rb file:
53
+
54
+ \code
55
+ require 'mkmf-rice'
56
+ create_makefile('test')
57
+ \endcode
58
+
59
+ Note that we use mkmf-rice instead of mkmf. This will ensure that the
60
+ extension will be linked with standard C++ library along with the Rice
61
+ library, and allow access to the Rice header files.
62
+
63
+ Next we create our extension and save it to test.cpp:
64
+
65
+ \code
66
+ extern "C"
67
+ void Init_Test()
68
+ {
69
+ }
70
+ \endcode
71
+
72
+ Note the extern "C" line above. This tells the compiler that the
73
+ function Init_Test should have C linkage and calling convention. This
74
+ turns off name mangling so that the Ruby interpreter will be able to
75
+ find the function (remember that Ruby is written in C, not C++).
76
+
77
+ So far we haven't put anything into the extension, so it isn't
78
+ particularly useful. The next step is to define a class so we can add
79
+ methods to it.
80
+
81
+
82
+ \subsection classes Defining clases
83
+
84
+ Defining a class in Rice is easy:
85
+
86
+ \code
87
+ #include "rice/Class.hpp"
88
+
89
+ using namespace Rice;
90
+
91
+ extern "C"
92
+ void Init_Test()
93
+ {
94
+ Class rb_cTest = define_class("Test");
95
+ }
96
+ \endcode
97
+
98
+ This will create a class called Test that inherits from Object. If we
99
+ wanted to inherit from a different class, we could easily do so:
100
+
101
+ \code
102
+ #include "rice/Class.hpp"
103
+
104
+ using namespace Rice;
105
+
106
+ extern "C"
107
+ void Init_Test()
108
+ {
109
+ Class rb_cMySocket = define_class("MySocket", rb_cIO);
110
+ }
111
+ \endcode
112
+
113
+ Note the prefix rb_c on the name of the class. This is a convention
114
+ that the Ruby interpreter and many extensions tend to use. It signifies
115
+ that this is a class and not some other type of object. Some other
116
+ naming conventions that are commonly used:
117
+
118
+ \li rb_c variable name prefix for a Class
119
+ \li rb_m variable name prefix for a Module
120
+ \li rb_e variable name prefix for an Exception type
121
+ \li rb_ function prefix for a function in the Ruby C API
122
+ \li rb_f_ function prefix to differentiate between an API function that
123
+ takes Ruby objects as arguments and one that takes C argument types
124
+ \li rb_*_s_ indicates the function is a singleton function
125
+ \li *_m suffix to indicate the function takes variable number of
126
+ arguments
127
+
128
+
129
+ Also note that we don't include "ruby.h" directly. Rice has a wrapper
130
+ for ruby.h that handles some compatibility issues across platforms and
131
+ Ruby versions. Always include Rice headers before including anything
132
+ that might include "ruby.h".
133
+
134
+ \subsection methods Defining methods
135
+
136
+ Now let's add a method to our class:
137
+
138
+ \code
139
+ #include "rice/Class.hpp"
140
+ #include "rice/String.hpp"
141
+
142
+ using namespace Rice;
143
+
144
+ Object test_hello(Object /* self */)
145
+ {
146
+ String str("hello, world");
147
+ return str;
148
+ }
149
+
150
+ extern "C"
151
+ void Init_Test()
152
+ {
153
+ Class rb_cTest =
154
+ define_class("Test")
155
+ .define_method("hello", &test_hello);
156
+ }
157
+ \endcode
158
+
159
+ Here we add a method Test#hello that simply returns the string
160
+ "Hello, World". The method takes self as an implicit parameter, but
161
+ isn't used, so we comment it out to prevent a compiler warning.
162
+
163
+ We could also add an #initialize method to our class:
164
+
165
+ \code
166
+ #include "rice/Class.hpp"
167
+ #include "rice/String.hpp"
168
+
169
+ using namespace Rice;
170
+
171
+ Object test_initialize(Object self)
172
+ {
173
+ self.iv_set("@foo", 42);
174
+ }
175
+
176
+ Object test_hello(Object /* self */)
177
+ {
178
+ String str("hello, world");
179
+ return str;
180
+ }
181
+
182
+ extern "C"
183
+ void Init_Test()
184
+ {
185
+ Class rb_cTest =
186
+ define_class("Test")
187
+ .define_method("initialize", &test_initialize);
188
+ .define_method("hello", &test_hello);
189
+ }
190
+ \endcode
191
+
192
+ The initialize method sets an instance variable @foo to the value 42.
193
+ The number is automatically converted to a Fixnum before doing the
194
+ assignment.
195
+
196
+ Note that we're chaining calls on the Class object. Most member
197
+ functions in Module and Class return a reference to self, so we can
198
+ chain as many calls as we want to define as many methods as we want.
199
+
200
+
201
+ \subsection data_types Wrapping C++ Types
202
+
203
+ It's useful to be able to define Ruby classes in a C++ style rather than
204
+ using the Ruby API directly, but the real power Rice is in wrapping
205
+ already-defined C++ types.
206
+
207
+ Let's assume we have the following C++ class that we want to wrap:
208
+
209
+ \code
210
+ class Test
211
+ {
212
+ public:
213
+ Test();
214
+ std::string hello();
215
+ };
216
+ \endcode
217
+
218
+ This is a C++ version of the Ruby class we just created in the previous
219
+ section. To wrap it:
220
+
221
+ \code
222
+ #include "rice/Data_Type.hpp"
223
+ #include "rice/Constructor.hpp"
224
+
225
+ using namespace Rice;
226
+
227
+ extern "C"
228
+ void Init_Test()
229
+ {
230
+ Data_Type<Test> rb_cTest =
231
+ define_class<Test>("Test")
232
+ .define_constructor(Constructor<Test>())
233
+ .define_method("hello", &Test::hello);
234
+ }
235
+ \endcode
236
+
237
+ This example is similar to the one before, but we use Data_Type<>
238
+ instead of Class and the template version of define_class() instead of
239
+ the non-template version. This creates a binding in the Rice library
240
+ between the Ruby class Test and the C++ class Test, so that we pass
241
+ member function pointers to define_method() and have conversions be done
242
+ automatically.
243
+
244
+ It's possible to write the conversion functions ourself (as we'll see
245
+ below), but Rice does all the dirty work for us.
246
+
247
+
248
+ \subsection conversions Type conversions
249
+
250
+ Let's look again at our example class:
251
+
252
+ \code
253
+ class Test
254
+ {
255
+ public:
256
+ Test();
257
+ std::string hello();
258
+ };
259
+ \endcode
260
+
261
+ When we wrote our class, we never wrote a single line of code to convert
262
+ the std::string returned by hello() into a Ruby type. Neverthless, the
263
+ conversion works, and when we write:
264
+
265
+ \code
266
+ test = Test.new
267
+ puts test.hello
268
+ \endcode
269
+
270
+ We get the expected result.
271
+
272
+ Rice has two template conversion functions to convert between C++ and
273
+ Ruby types:
274
+
275
+ \code
276
+ template<typename T>
277
+ T from_ruby(Object x);
278
+
279
+ template<typename T>
280
+ Object to_ruby(T const & x);
281
+ \endcode
282
+
283
+ Rice has included by default specializations for many of the builtin
284
+ types. To define your own conversion, you can write a specialization:
285
+
286
+ \code
287
+ template<>
288
+ Foo from_ruby<Foo>(Object x)
289
+ {
290
+ // ...
291
+ }
292
+
293
+ template<>
294
+ Object to_ruby<Foo>(Foo const & x)
295
+ {
296
+ // ...
297
+ }
298
+ \endcode
299
+
300
+ The implementation of these functions would, of course, depend on the
301
+ implementation of Foo.
302
+
303
+
304
+ \subsection data_conversions Conversions for wrapped C++ types
305
+
306
+ Take another look at the wrapper we wrote for the Test class:
307
+
308
+ \code
309
+ extern "C"
310
+ void Init_Test()
311
+ {
312
+ Data_Type<Test> rb_cTest =
313
+ define_class<Test>("Test")
314
+ .define_constructor(Constructor<Test>())
315
+ .define_method("hello", &Test::hello);
316
+ }
317
+ \endcode
318
+
319
+ When we called define_class<Test>, it created a Class for us and
320
+ automatically registered the new Class with the type system, so that the
321
+ calls:
322
+
323
+ \code
324
+ Data_Object<Foo> obj(new Foo);
325
+ Foo * f = from_ruby<Foo *>(obj);
326
+ Foo const * f = from_ruby<Foo const *>(obj);
327
+ \endcode
328
+
329
+ work as expected.
330
+
331
+ The Data_Object class is a wrapper for the Data_Wrap_Struct and the
332
+ Data_Get_Struct macros in C extensions. It can be used to wrap or
333
+ unwrap any class that has been assigned to a Data_Type. It inherits
334
+ from Object, so any member functions we can call on an Object we can
335
+ also call on a Data_Object:
336
+
337
+ \code
338
+ Object object_id = obj.call("object_id");
339
+ std::cout << object_id << std::endl;
340
+ \endcode
341
+
342
+ The Data_Object class can be used to wrap a newly-created object:
343
+
344
+ \code
345
+ Data_Object<Foo> foo(new Foo);
346
+ \endcode
347
+
348
+ or to unwrap an already-created object:
349
+
350
+ \code
351
+ VALUE obj = ...;
352
+ Data_Object<Foo> foo(obj);
353
+ \endcode
354
+
355
+ A Data_Object functions like a smart pointer:
356
+
357
+ \code
358
+ Data_Object<Foo> foo(obj);
359
+ foo->foo();
360
+ std::cout << *foo << std::endl;
361
+ \endcode
362
+
363
+ Like a VALUE or an Object, data stored in a Data_Object will be marked
364
+ by the garbage collector as long as the Data_Object is on the stack.
365
+
366
+
367
+ \subsection exception Exceptions
368
+
369
+ Suppose we added a member function to our example class that throws an
370
+ exception:
371
+
372
+ \code
373
+ class MyException
374
+ : public std::exception
375
+ {
376
+ };
377
+
378
+ class Test
379
+ {
380
+ public:
381
+ Test();
382
+ std::string hello();
383
+ void error();
384
+ };
385
+ \endcode
386
+
387
+ If we were to wrap this function:
388
+
389
+ \code
390
+ extern "C"
391
+ void Init_Test()
392
+ {
393
+ Data_Type<Test> rb_cTest =
394
+ define_class<Test>("Test")
395
+ .define_constructor(Constructor<Test>())
396
+ .define_method("hello", &Test::hello)
397
+ .define_method("error", &Test::error);
398
+ }
399
+ \endcode
400
+
401
+ and call it from inside Ruby:
402
+
403
+ \code
404
+ test = Test.new
405
+ test.error()
406
+ \endcode
407
+
408
+ we would get an exception. Rice will automatically convert any
409
+ C++ exception it catches into a Ruby exception. But what if we wanted
410
+ to use a custom eror message when we convert the exception, or what if
411
+ we wanted to convert to a different type of exception? We can write
412
+ this:
413
+
414
+ \code
415
+ extern "C"
416
+ void Init_Test()
417
+ {
418
+ Data_Type<Test> rb_cTest =
419
+ define_class<Test>("Test")
420
+ .add_handler<MyException>(handle_my_exception)
421
+ .define_constructor(Constructor<Test>())
422
+ .define_method("hello", &Test::hello)
423
+ .define_method("error", &Test::error);
424
+ }
425
+ \endcode
426
+
427
+ The handle_my_exception function need only rethrow the exception as a
428
+ Rice::Exception:
429
+
430
+ \code
431
+ void handle_my_exception(MyException const & ex)
432
+ {
433
+ throw Exception(rb_eRuntimeError, "Goodnight, moon");
434
+ }
435
+ \endcode
436
+
437
+ And what if we want to call Ruby code from C++? These exceptions are
438
+ also converted:
439
+
440
+ \code
441
+ Object o;
442
+ o.call("some_function_that_raises", 42);
443
+
444
+ protect(rb_raise, rb_eRuntimeError, "some exception msg");
445
+ \endcode
446
+
447
+ Internally whenever Rice catches a C++ or a Ruby exception, it converts
448
+ it to an Exception object. This object will later be re-raised as a
449
+ Ruby exception when control is returned to the Ruby VM.
450
+
451
+ Rice uses a similar class called Jump_Tag to handle symbols thrown by
452
+ Ruby's throw/catch or other non-local jumps from inside the Ruby VM.
453
+
454
+
455
+ \subsection builtin Builtin types
456
+
457
+ You've seen this example:
458
+
459
+ \code
460
+ Object object_id = obj.call("object_id");
461
+ std::cout << object_id << std::endl;
462
+ \endcode
463
+
464
+ Rice mimics the Ruby class hierarchy as closely as it can given that C++
465
+ is statically typed. In fact, the above code also works for Classes:
466
+
467
+ \code
468
+ Class rb_cTest = define_class<Test>("Test");
469
+ Object object_id = rb_cTest.call("object_id");
470
+ std::cout << object_id << std::endl;
471
+ \endcode
472
+
473
+ Rice provides builtin wrappers for many builtin Ruby types, including:
474
+
475
+ \li Object
476
+ \li Module
477
+ \li Class
478
+ \li String
479
+ \li Array
480
+ \li Hash
481
+ \li Struct
482
+ \li Symbol
483
+ \li Exception
484
+
485
+ The Array and Hash types can even be iterated over the same way one
486
+ would iterate over an STL container:
487
+
488
+ \code
489
+ Array a;
490
+ a.push(to_ruby(42));
491
+ a.push(to_ruby(43));
492
+ a.push(to_ruby(44));
493
+ Array::iterator it = a.begin();
494
+ Array::iterator end = a.end();
495
+ for(; it != end; ++it)
496
+ {
497
+ std::cout << *it << std::endl;
498
+ }
499
+ \endcode
500
+
501
+ STL algorithms should also work as expected on Array and Hash containers.
502
+
503
+
504
+ \subsection inheritance Inheritance
505
+
506
+ Inheritance is a tricky problem to solve in extensions. This is because
507
+ wrapper functions for base classes typically don't know how to accept
508
+ pointers to derived classes. It is possible to write this logic, but
509
+ the code is nontrivial.
510
+
511
+ Forunately Rice handles this gracefully:
512
+
513
+ \code
514
+ class Base
515
+ {
516
+ public:
517
+ virtual void foo();
518
+ };
519
+
520
+ class Derived
521
+ : public Base
522
+ {
523
+ };
524
+
525
+ extern "C"
526
+ void Init_Test()
527
+ {
528
+ Data_Type<Base> rb_cBase =
529
+ define_class<Base>("Base")
530
+ .define_method("foo", &Base::foo);
531
+ Data_Type<Derived> rb_cDerived =
532
+ define_class<Derived, Base>("Derived");
533
+ }
534
+ \endcode
535
+
536
+ The second template parameter to define_class indicates that Derived
537
+ inherits from Base.
538
+
539
+ Rice does not yet support multiple inheritance, but it is believed that
540
+ this is possible through the use of mixins.
541
+
542
+
543
+ \subsection overloading Overloaded functions
544
+
545
+ If you try to create a member function pointer to an overloaded
546
+ function, you will get an error. So how do we wrap classes that have
547
+ overloaded functions?
548
+
549
+ Consider a class that uses this idiom for accessors:
550
+
551
+ \code
552
+ class Container
553
+ {
554
+ size_t capacity(); // Get the capacity
555
+ void capacity(size_t cap); // Set the capacity
556
+ };
557
+ \endcode
558
+
559
+ We can wrap this class by using typedefs:
560
+
561
+ \code
562
+ extern "C"
563
+ void Init_Container()
564
+ {
565
+ typedef size_t (*Container::get_capacity)();
566
+ typedef void (*Container::set_capacity)(size_t);
567
+
568
+ Data_Type<Container> rb_cContainer =
569
+ define_class<Container>("Container")
570
+ .define_method("capacity", get_capacity(&Container::capacity))
571
+ .define_method("capacity=", set_capacity(&Container::capacity))
572
+ }
573
+ \endcode
574
+
575
+ A future version of Rice may provide a simplified interface for this.
576
+
577
+
578
+ \subsection user_defined_conversions User-defined type conversions
579
+
580
+ Rice provides default conversions for many built-in types. Sometimes,
581
+ however, the default conversion is not their right conversion. For
582
+ example, consider a function:
583
+
584
+ \code
585
+ void foo(char * x);
586
+ \endcode
587
+
588
+ Is x a pointer to a single character or a pointer to the first character
589
+ of a null-terminated string or a pointer to the first character of an
590
+ array of char?
591
+
592
+ Because the second case is the most common use case (a pointer to the
593
+ first character of a C string), Rice provides a default conversion that
594
+ treats a char * as a C string. But suppose the above function takes a
595
+ pointer to a char instead?
596
+
597
+ If we write this:
598
+
599
+ \comment : -- this comment is to satisfy vim syntax highlighting --
600
+
601
+ \code
602
+ extern "C"
603
+ void Init_Test()
604
+ {
605
+ define_global_function("foo", &foo);
606
+ }
607
+ \endcode
608
+
609
+ It will likely have the wrong behavior.
610
+
611
+ To avoid this problem, it is necessary to write a wrapper function:
612
+
613
+ \code
614
+ Object wrap_foo(Object o)
615
+ {
616
+ char c = from_ruby<char>(o);
617
+ foo(&c);
618
+ return to_ruby(c);
619
+ }
620
+
621
+ extern "C"
622
+ void Init_Test()
623
+ {
624
+ define_global_function("foo", &wrap_foo);
625
+ }
626
+ \endcode
627
+
628
+ Note that the out parameter is returned from wrap_foo, as Ruby does not
629
+ have pass-by-variable-reference (it uses pass-by-object-reference).
630
+
631
+ Future versions of Rice will have a cleaner way of dealing with this.
632
+
633
+
634
+ \section default_arguments Default Arguments
635
+
636
+ Going back to our initial C++ class example, lets say that hello() now
637
+ take a few arguments for what to return, one which has a default value:
638
+
639
+ \code
640
+ class Test
641
+ {
642
+ public:
643
+ Test();
644
+ std::string hello(std::string first, std::string second = "world");
645
+ };
646
+ \endcode
647
+
648
+ As default parameter information is not available through templates,
649
+ it's necessary to define this in Rice explicitly using Rice::Arg:
650
+
651
+ \code
652
+ #include "rice/Data_Type.hpp"
653
+ #include "rice/Constructor.hpp"
654
+
655
+ using namespace Rice;
656
+
657
+ extern "C"
658
+ void Init_Test()
659
+ {
660
+ Data_Type<Test> rb_cTest =
661
+ define_class<Test>("Test")
662
+ .define_constructor(Constructor<Test>())
663
+ .define_method("hello",
664
+ &Test::hello,
665
+ (Arg("hello"), Arg("second") = "world")
666
+ );
667
+ }
668
+ \endcode
669
+
670
+ The syntax here is simply Arg(nameOfParameter)[ = defaultValue]. The name of the
671
+ parameter is not important (more for readability, and the future for when/if Ruby
672
+ gets named parameters), but the value set via operator= must match the type
673
+ of the given parameter.
674
+
675
+ These Rice::Arg objects must be in the correct order, and if there are more than
676
+ one of them they must be surrounded in parentheses, as above, or the compilation
677
+ will fail.
678
+
679
+ It may be required to explicitly cast the default argument values to their
680
+ appropriate types:
681
+
682
+ \code
683
+ .define_method("hello",
684
+ &Test::hello,
685
+ (Arg("hello"), Arg("second") = (std::string)"world")
686
+ );
687
+ \endcode
688
+
689
+ With this, Ruby will now know about the default arguments, and this wrapper
690
+ can be used as expected:
691
+
692
+ \code
693
+ t = Test.new
694
+ t.hello("hello")
695
+ t.hello("goodnight", "moon")
696
+ \endcode
697
+
698
+ This will also work with Constructors:
699
+
700
+ \code
701
+ .define_constructor(Constructor<SomeClass, int, int>(),
702
+ ( Arg("arg1") = 1, Arg("otherArg") = 12 );
703
+ \endcode
704
+
705
+ \section director Director
706
+
707
+ As polymorphism is the most important tennant of Object Oriented Programming,
708
+ it's important that Rice supports polymorphic calls travelling between C++
709
+ and Ruby seemlessly. Super calls from Ruby subclasses back into C++ already work,
710
+ but enabling the other direction requires some extra work. While this isn't
711
+ something Rice can do on it's own, the Rice::Director class, coupled with
712
+ Rice::Data_Type::define_director exposes this functionality cleanly.
713
+
714
+ Like SWIG_Director, Rice::Director is a class that is used to build a proxy class
715
+ to properly send execution up or down the object heiarchy for that class. Take
716
+ the following class:
717
+
718
+ \code
719
+ class VirtualBase {
720
+ public:
721
+ VirtualBase();
722
+ virtual int doWork();
723
+ virtual int processWorker() = 0;
724
+ };
725
+ \endcode
726
+
727
+ Due to the abstract nature of this class, it will not work at all with Rice
728
+ in it's current form. Any attempt to do so will cause a compilation error due to
729
+ this class not being constructable. Even without the pure virtual function, any
730
+ call to VirtualBase::doWork will stop at the C++ level and will not pass down into
731
+ any Ruby subclasses.
732
+
733
+ To properly wrap both of these methods, you'll need to build a proxy class
734
+ that subclasses Rice::Director along with a few methods:
735
+
736
+ \code
737
+ #include "rice/Director.hpp"
738
+
739
+ class VirtualBaseProxy : public VirtualBase, public Rice::Director {
740
+ public:
741
+ VirtualBaseProxy(Object self) : Rice::Director(self) { }
742
+
743
+ virtual int doWork() {
744
+ return from_ruby<int>( getSelf().call("do_work") );
745
+ }
746
+
747
+ int default_doWork() {
748
+ return VirtualBase::doWork();
749
+ }
750
+
751
+ virtual int processWorker() {
752
+ return from_ruby<int>( getSelf().call("process_worker") );
753
+ }
754
+
755
+ int default_processWorker() {
756
+ raisePureVirtual();
757
+ }
758
+ };
759
+ \endcode
760
+
761
+ There is a lot going on here, so we'll go through each part.
762
+
763
+ \code
764
+ class VirtualBaseProxy : public Virtualbase, public Rice::Director {
765
+ \endcode
766
+
767
+ First, the class needs to subclass both the virtual class and Rice::Director class.
768
+
769
+ \code
770
+ public:
771
+ VirtualBaseProxy(Object self) : Rice::Director(self) { }
772
+ \endcode
773
+
774
+ For Rice::Director to work its magic, every instance of this class needs to
775
+ have a handle to the Ruby instance of this class as well. The constructor
776
+ must take a Rice::Object as the first argument, then any other arguments follow
777
+ and should be passed back to the superclass as needed. The code here is the
778
+ minimum required for a Rice::Director proxy.
779
+
780
+ \code
781
+ virtual int doWork() {
782
+ return from_ruby<int>( getSelf().call("do_work") );
783
+ }
784
+
785
+ int default_doWork() {
786
+ return VirtualBase::doWork();
787
+ }
788
+ \endcode
789
+
790
+ The two methods seen here directly correspond to the two code directions this class
791
+ opens up. The virtual method is this class's hook into C++'s polymorphism. Any calls
792
+ that need to be forwarded into Ruby are done as specified here: get the Ruby object
793
+ for the instance of this class, call Rice::Object::call, and if necessary convert
794
+ the return value from Ruby back into C++ types.
795
+
796
+ The default_doWork method will be used as Rice's hookup of calling back up the
797
+ heirarchy (wrapping is below). This method needs to do one of two things: call
798
+ up the class heirarchy, as seen here, or call raisePureVirtual() as seen in the
799
+ processWorker example:
800
+
801
+ \code
802
+ int default_processWorker() {
803
+ raisePureVirtual();
804
+ }
805
+ \endcode
806
+
807
+ The method raisePureVirtual() exists to allow wrapping a pure virtual method into Ruby
808
+ but making sure any users of this extension are informed quickly that there's nothing
809
+ in the C++ to call for the given method.
810
+
811
+ Once the proxy class is built, it's time to wrap it into Ruby:
812
+
813
+ \code
814
+ extern "C"
815
+ void Init_virtual() {
816
+ define_class<VirtualBase>("VirtualBase")
817
+ .define_director<VirtualBaseProxy>()
818
+ .define_constructor(Constructor<VirtualBaseProxy, Rice::Object>())
819
+ .define_method("do_work", &VirtualBaseProxy::default_doWork)
820
+ .define_method("process_worker", &VirtualBaseProxy::default_processWorker);
821
+ }
822
+ \endcode
823
+
824
+ The wrapping is the same as is described earlier in this document. Expose the class
825
+ VirtualBase, and register VirtualBaseProxy as a director proxy of VirtualBase with
826
+ Rice::Data_Type::define_director, then define methods pointing to the proxy object as necessary.
827
+
828
+ You must use the Rice::Director proxy class in the Constructor line, this allows proper
829
+ object construction / destruction of the types in question.
830
+
831
+ \section implicit_cast Implicit Casting
832
+
833
+ There are times when a library exposes classes that while unrelated are
834
+ built to be interchangeable across the library. One example of this,
835
+ taken from Ogre, are the Degree and Radian classes. When a given method
836
+ takes a Radian, you're free to pass in a Degree, and vice versa.
837
+
838
+ Rice cannot automatically figure out if this kind of functionality is
839
+ possible in a given library but it does have a simple API for defining
840
+ these relationships: Rice::define_implicit_cast<From, To>().
841
+
842
+ \code
843
+ class Degree { ... };
844
+ class Radian { ... };
845
+
846
+ extern "C"
847
+ void Init_implicit() {
848
+ define_class<Degree>()
849
+ ...;
850
+ define_class<Radian>()
851
+ ...;
852
+
853
+ define_implicit_cast<Degree, Radian>();
854
+ define_implicit_cast<Radian, Degree>();
855
+ }
856
+ \endcode
857
+
858
+ This support is still being fleshed out and has a few requirements for
859
+ proper use:
860
+
861
+ \li The two types must be bound in Rice before defining the cast.
862
+ \li The classes must have constructors that take the other type.
863
+ \li This feature cannot be used with fundamental types yet.
864
+
865
+ To see a full example of this feature, please check out
866
+ test/test_Data_Type.cpp.
867
+
868
+ \section motivation Motivation
869
+
870
+ There are a number of common problems when writing C or C++ extensions
871
+ for Ruby:
872
+
873
+ \li Type safety. It is easy to mix-up integral types such as ID and
874
+ VALUE. Some of the functions in the Ruby API are not consistent with
875
+ which types they take (e.g. rb_const_defined takes an ID and
876
+ rb_mod_remove_const takes a Symbol).
877
+
878
+ \li DRY principle. Specifying the number of arguments that each wrapped
879
+ function takes is easy to get wrong. Adding a new argument to the
880
+ function means that the number of arguments passed to rb_define_method
881
+ must also be updated.
882
+
883
+ \li Type conversion. There are many different functions to convert data
884
+ to and from ruby types. Many of them have different semantics or
885
+ different forms. For example, to convert a string, one might use the
886
+ StringValue macro, but to convert a fixnum, one might use FIX2INT.
887
+ Unwrapping previously wrapped C data uses yet another form.
888
+
889
+ \li Exception safety. It is imperative that C++ exceptions never make
890
+ their way into C code, and it is also imperative that a Ruby exception
891
+ never escape while there are objects on the stack with nontrivial
892
+ destructors. Rules for when it is okay to use which exceptions are
893
+ difficult to get right, especially as code is maintained through time.
894
+
895
+ \li Thread safety. Because the Ruby interpreter is not threads-safe,
896
+ the Ruby interpreter must not be run from more than one thread.
897
+ Because of tricks the GC and scheduler play with the C stack, it's not
898
+ enough to ensure that only one thread runs the interpreter at any
899
+ given time; once the interpreter has been run from one thread, it must
900
+ only ever be run from that thread in the future. Additionally,
901
+ because Ruby copies the stack when it switches threads, C++ code must
902
+ be careful not to access objects in one Ruby thread that were created
903
+ on the stack in another Ruby thread.
904
+
905
+ \li C-based API. The Ruby API is not always convenient for accessing
906
+ Ruby data structurs such as Hash and Array, especially when writing C++
907
+ code, as the interface for these containers is not consistent with
908
+ standard containers.
909
+
910
+ \li Calling convention. Function pointers passed into the Ruby API must
911
+ follow the C calling convention. This means that it is not possible to
912
+ pass a pointer to a template function or static member function (that
913
+ is, it will work on some platforms, but isn't portable).
914
+
915
+ \li Inheritance. When wrapping C++ objects, it is easy to store a
916
+ pointer to a derived class, but then methods in the base class must have
917
+ knowledge of the derived class in order to unwrap the object. It is
918
+ possible to always store a pointer to the base class and then
919
+ dynamic_cast the pointer to the derived type when necessary, but this
920
+ can be slow and cumbersome, and it isn't likely to work with multiple
921
+ inheritance. A system that properly handles inheritance for all corner
922
+ cases is nontrivial.
923
+
924
+ \li Multiple inheritance. C++ supports true multiple inheritance, but
925
+ the Ruby object model uses single inheritance with mixins. When
926
+ wrapping a library whose public interface uses multiple inheritance,
927
+ care must be taken in constructing the mapping.
928
+
929
+ \li GC safety. All live Ruby objects must be marked during the garbage
930
+ collector's mark phase, otherwise they will be prematurely destroyed.
931
+ The general rule is that object references stored on the heap should be
932
+ either registered with rb_gc_register_address or marked by a data
933
+ object's mark function; object references stored on the stack will be
934
+ automatically marked, provided the Ruby interpreter was properly
935
+ initialized at startup.
936
+
937
+ \li Callbacks. C implements callbacks via function pointers, while ruby
938
+ typically implements callbacks via procs. Writing an adapter function
939
+ to call the proc is not difficult, but there is much opportunity for
940
+ error (particularly with exception-safety).
941
+
942
+ \li Data serialization. By default data objects defined at the C layer
943
+ are not marshalable. The user must explicitly define functions to
944
+ marshal the data member-by-member.
945
+
946
+ Rice addresses these issues in many ways:
947
+
948
+ \li Type safety. Rice provides encapsulation for all builtin types,
949
+ such as Object, Identifier, Class, Module, and String. It
950
+ automatically checks the dynamic type of an object before constructing
951
+ an instance of a wrapper.
952
+
953
+ \li DRY principle. Rice uses introspection through the use of templates
954
+ and function overloading to automatically determine the number and types
955
+ of arguments to functions. Default arguments must still be handled
956
+ explicitly, however.
957
+
958
+ \li Type conversions. Rice provides cast-style to_ruby<> and
959
+ from_ruby<> template functions to simplify explicit type conversions.
960
+ Automatic type conversions for parameters and return values are
961
+ generated for all wrapped functions.
962
+
963
+ \li Exception safety. Rice automatically converts common exceptions and
964
+ provides a mechanism for converting user-defined exception types. Rice
965
+ also provides convenience functions for converting exceptions when
966
+ calling back into ruby code.
967
+
968
+ \li Thread safety. Rice provides no mechanisms for dealing with thread
969
+ safety. Many common thread safety issues should be alleviated by YARV,
970
+ which supports POSIX threads.
971
+
972
+ \li C++-based API. Rice provides an object-oriented C++-style API to
973
+ most common functions in the Ruby C API.
974
+
975
+ \li Calling convention. Rice automatically uses C calling convention
976
+ for all function pointers passed into the Ruby API.
977
+
978
+ \li Inheritance. Rice provides automatic conversion to the base class
979
+ type when a wrapped member function is called on the base class.
980
+
981
+ \li Multiple inheritance. Rice provides no mechanism for multiple
982
+ inheritance. Multiple inheritance can be simulated via mixins, though
983
+ this is not yet as easy as it could be.
984
+
985
+ \li GC safety. Rice provides a handful of convenience classes for
986
+ interacting with the garbage collector. There are still basic rules
987
+ which must be followed to ensure that objects get properly destroyed.
988
+
989
+ \li Callbacks. Rice provides a handful of convenience classes for
990
+ dealing with callbacks.
991
+
992
+ \li Data serialization. Rice provides no mechanism for data
993
+ serialization, but it is likely this may be added in a future release.
994
+
995
+
996
+ \section what_not What Rice is Not
997
+
998
+ There are a number projects which server similar functions to Rice. Two
999
+ such popular projects are SWIG and Boost.Python. Rice has some
1000
+ distinct features which set it apart from both of these projects.
1001
+
1002
+ Rice is not trying to replace SWIG. Rice is not a generic wrapper
1003
+ interface generator. Rice is a C++ library for interfacing with the
1004
+ Ruby C API. This provides a very natural way for C++ programmers to
1005
+ wrap their C++ code, without having to learn a new domain-specific
1006
+ language. However, there is no reason why SWIG and Rice could not work
1007
+ together; a SWIG module could be written to generate Rice code. Such a
1008
+ module would combine the portability of SWIG with the maintainability of
1009
+ Rice (I have written extensions using both, and I have found Rice
1010
+ extensions to be more maintainable when the interface is constantly
1011
+ changing. Your mileage may vary).
1012
+
1013
+ Rice is also not trying to simply be a Ruby version of Boost.Python.
1014
+ Rice does use some of the same template tricks that Boost.Python uses,
1015
+ however there are some important distinctions. First of all,
1016
+ Boost.Python attempts to create a declarative DSL in C++ using
1017
+ templates. Rice is a wrapper around the Ruby C API and attempts to make
1018
+ its interface look like an OO version of the API; this means that class
1019
+ declarations look procedural rather than declarative. Secondly, the
1020
+ Ruby object model is different from the python object model. This is
1021
+ reflected in the interface to Rice; it mimics the Ruby object model at
1022
+ the C++ level. Thirdly, Rice uses Ruby as a code generator; I find this
1023
+ to be much more readable than using the Boost preprocessor library.
1024
+
1025
+
1026
+ \section history History
1027
+
1028
+ Rice originated as a project to interface with C++-based trading
1029
+ software at Automated Trading Desk in Mount Pleasant, South Carolina.
1030
+ The Ruby bindings for Swig were at the time less mature than they are
1031
+ today, and did not suit the needs of the project.
1032
+
1033
+ Excruby was written not as a wrapper for the Ruby API, but rather as a
1034
+ set of helper functions and classes for interfacing with the Ruby
1035
+ interpreter in an exception-safe manner. Over the course of five years,
1036
+ the project grew into wrappers for pieces of the API, but the original
1037
+ helper functions remained as part of the public interface.
1038
+
1039
+ This created confusion for the users of the library, because there were
1040
+ multiple ways of accomplishing most tasks -- directly through the C API,
1041
+ through a low-level wrapper around the C API, and through a high-level
1042
+ abstraction of the lower-level interfaces.
1043
+
1044
+ Rice was then born in an attempt to clean up the interface. Rice keeps
1045
+ the lower-level wrappers, but as an implementation detail; the public
1046
+ interface is truly a high-level abstraction around the Ruby C API.
1047
+
1048
+
1049
+ \section gc The GC
1050
+
1051
+ \li Objects are not automatically registered with the garbage collector.
1052
+
1053
+ \li If an Object is on the stack, it does not need to be registered with
1054
+ the garbage collector.
1055
+
1056
+ \li If an Object is allocated on the heap or if it is a member of an
1057
+ object that might be allocated on the heap, use an
1058
+ Address_Registration_Guard to register the object with the garbage
1059
+ collector.
1060
+
1061
+ \li If a reference counted object is being wrapped, or if another type
1062
+ of smart pointer is wrapped, ensure that only one mechanism is used to
1063
+ destroy the object. In general, the smart pointer manages the
1064
+ allocation of the object, and Ruby should hold only a reference to the
1065
+ smart pointer. When the garbage collector determines that it is time to
1066
+ clean up the object, the smart pointer will be destroyed, decrementing
1067
+ the reference count; when the reference count drops to 0, underlying
1068
+ object will be destroyed.
1069
+
1070
+
1071
+ \section embedding Embedding
1072
+
1073
+ You can embed the Ruby interpter in your application by using the VM
1074
+ class:
1075
+
1076
+ \code
1077
+ int main(int argc, char * argv[])
1078
+ {
1079
+ Rice::VM vm(argc, argv);
1080
+ vm.run()
1081
+ }
1082
+ \endcode
1083
+
1084
+ If the VM is not initialized from main() -- from a callback, for example
1085
+ -- then you may need to initialize the stack whenever you use Rice or
1086
+ the Ruby API:
1087
+
1088
+ \code
1089
+ std::auto_ptr<Rice::VM> vm;
1090
+ Rice::Object obj;
1091
+
1092
+ void some_application_extension_init()
1093
+ {
1094
+ vm.reset(new Rice::VM("some_application"));
1095
+ }
1096
+
1097
+ void some_application_extension_callback()
1098
+ {
1099
+ // Need to initialize the stack here, because we don't know if
1100
+ // we are at the same stack depth as when the VM was initialized
1101
+ vm->init_stack();
1102
+
1103
+ // Now do some work...
1104
+ obj->call("some_callback_function")
1105
+ }
1106
+ \endcode
1107
+
1108
+ Be aware that initializing the Ruby VM can cause a call to exit() if
1109
+ certain command-line options are specified. This has two implications:
1110
+
1111
+ \li an application that constructs a Ruby VM may terminate
1112
+ unexpectedly if the options passed to the interpreter are not tightly
1113
+ controlled (a security issue), and
1114
+
1115
+ \li an application that constructs a Ruby VM should not have any
1116
+ objects with nontrivial destructors on the stack when the VM is
1117
+ created, otherwise those objects might not get correctly destructed.
1118
+
1119
+ vim:ft=cpp:tw=72:ts=2:sw=2:fo=cqrtn:noci:si