diff --git a/Doc/Manual/Ruby.html b/Doc/Manual/Ruby.html index 30cb1ae0a..6e8e65aac 100644 --- a/Doc/Manual/Ruby.html +++ b/Doc/Manual/Ruby.html @@ -47,48 +47,50 @@
class MyArray {
public:
// Construct an empty array
MyArray();
// Return the size of this array
size_t length() const;
};
%extend MyArray {
// MyArray#size is an alias for MyArray#length
size_t size() const {
return self->length();
}
}
- A better solution is to use the %alias directive (unique to SWIG's Ruby module). The previous example could then be rewritten as:
// MyArray#size is an alias for MyArray#length-
%alias MyArray::length "size";
class MyArray {
public:
// Construct an empty array
MyArray();
// Return the size of this array
size_t length() const;
};
Multiple aliases can be associated with a method by providing a comma-separated list of aliases to the %alias directive, e.g.
%alias MyArray::length "amount,quantity,size";-
From an end-user's standpoint, there's no functional difference between these
two approaches; i.e. they should get the same result from calling either MyArray#size or MyArray#length. However, when the %alias directive is
used, SWIG doesn't need to generate all of the wrapper code that's usually
@@ -1020,19 +1022,19 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
%rename("is_it_safe?") is_it_safe();
%typemap(out) int is_it_safe
"$result = ($1 != 0) ? Qtrue : Qfalse;";
int is_it_safe();
- A better solution is to use the %predicate directive (unique to SWIG's Ruby module) to designate a method as a predicate method. For the previous example, this would look like:
%predicate is_it_safe();-
int is_it_safe();
This method would be invoked from Ruby code like this:
irb(main):001:0> Example::is_it_safe?-
true
The %predicate directive is implemented using SWIG's
"features" mechanism and so the same name matching rules used for other kinds
of features apply (see the chapter on "Customization
@@ -1055,6 +1057,35 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
"features" mechanism and so the same name matching rules used for other kinds
of features apply (see the chapter on "Customization
Features") for more details).
Often times a C++ library will expose properties through getter and setter methods. For example:
+class Foo {
+ Foo() {}
+
+ int getValue() { return value_; }
+
+ void setValue(int value) { value_ = value; }
+
+private:
+ int value_;
+};
+ By default, SWIG will expose these methods to Ruby as get_value and set_value. However, it more natural for these methods to be exposed in Ruby as value and value=. That allows the methods to be used like this:
+irb(main):001:0> foo = Foo.new() +irb(main):002:0> foo.value = 5 +irb(main):003:0> puts foo.value+
This can be done by using the %rename directive:
+%rename("value") Foo::getValue();
+%rename("value=") Foo::setValue(int value);
+
+
r, c = Example.get_dimensions(m)
- The SWIG %exception directive can be used to define a user-definable +
The SWIG %exception directive can be used to define a user-definable exception handler that can convert C/C++ errors into Ruby exceptions. The chapter on Customization Features contains more details, but suppose you have a C++ class like the following :
class DoubleArray {
private:
int n;
double *ptr;
public:
// Create a new array of fixed size
DoubleArray(int size) {
ptr = new double[size];
n = size;
}
// Destroy an array
~DoubleArray() {
delete ptr;
}
// Return the length of the array
int length() {
return n;
}
// Get an array item and perform bounds checking.
double getitem(int i) {
if ((i >= 0) && (i < n))
return ptr[i];
else
throw RangeError();
}
// Set an array item and perform bounds checking.
void setitem(int i, double val) {
if ((i >= 0) && (i < n))
ptr[i] = val;
else {
throw RangeError();
}
}
};
+ class DoubleArray {
private:
int n;
double *ptr;
public:
// Create a new array of fixed size
DoubleArray(int size) {
ptr = new double[size];
n = size;
}
+
// Destroy an array
~DoubleArray() {
delete ptr;
}
+
// Return the length of the array
int length() {
return n;
}
// Get an array item and perform bounds checking.
double getitem(int i) {
if ((i >= 0) && (i < n))
return ptr[i];
else
throw RangeError();
}
+
// Set an array item and perform bounds checking.
void setitem(int i, double val) {
if ((i >= 0) && (i < n))
ptr[i] = val;
else {
throw RangeError();
}
}
};
Since several methods in this class can throw an exception for an out-of-bounds
@@ -1152,7 +1188,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
following in an interface file:
%exception {
try {
$action
}
catch (const RangeError&) {
static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);
rb_raise(cpperror, "Range error.");
}
}
class DoubleArray {
...
};
+ %exception {
try {
$action
}
catch (const RangeError&) {
static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);
rb_raise(cpperror, "Range error.");
}
}
class DoubleArray {
...
};
The exception handling code is inserted directly into generated wrapper
@@ -1165,7 +1201,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
handler to only apply to specific methods like this:
%exception getitem {
try {
$action
}
catch (const RangeError&) {
static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);
rb_raise(cpperror, "Range error in getitem.");
}
}
%exception setitem {
try {
$action
}
catch (const RangeError&) {
static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);
rb_raise(cpperror, "Range error in setitem.");
}
}
+ %exception getitem {
try {
$action
}
catch (const RangeError&) {
static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);
rb_raise(cpperror, "Range error in getitem.");
}
}
%exception setitem {
try {
$action
}
catch (const RangeError&) {
static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);
rb_raise(cpperror, "Range error in setitem.");
}
}
In this case, the exception handler is only attached to methods and functions
@@ -1175,14 +1211,103 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
exception handling. See the chapter on Customization
Features for more examples.
When raising a Ruby exception from C/C++, use the rb_raise() function - as shown above. The first argument passed to rb_raise() is the - exception type. You can raise a custom exception type (like the cpperror - example shown above) or one of the built-in Ruby exception types. For a list of - the standard Ruby exception classes, consult a Ruby reference such as - Programming Ruby. -
-There are three ways to raise exceptions from C++ code to Ruby.
+The first way is to use SWIG_exception(int code, const char *msg). The following table shows the mappings from SWIG error codes to Ruby exceptions:
+| SWIG_MemoryError | +rb_eNoMemError | +
| SWIG_IOError | +rb_eIOError | +
| SWIG_RuntimeError | +rb_eRuntimeError | +
| SWIG_IndexError | +rb_eIndexError | +
| SWIG_TypeError | +rb_eTypeError | +
| SWIG_DivisionByZero | +rb_eZeroDivError | +
| SWIG_OverflowError | +rb_eRangeError | +
| SWIG_SyntaxError | +rb_eSyntaxError | +
| SWIG_ValueError | +rb_eArgError | +
| SWIG_SystemError | +rb_eFatal | +
| SWIG_AttributeError | +rb_eRuntimeError | +
| SWIG_NullReferenceError | +rb_eNullReferenceError* | +
| SWIG_ObjectPreviouslyDeletedError | +rb_eObjectPreviouslyDeleted* | +
| SWIG_UnknownError | +rb_eRuntimeError | +
| * These error classes are created by SWIG and are not built-in Ruby exception classes | +|
The second way to raise errors is to use SWIG_Raise(obj, type, desc). Obj is a C++ instance of an exception class, type is a string specifying the type of exception (for example, "MyError") and desc is the SWIG description of the exception class. For example:
+%raise(SWIG_NewPointerObj(e, SWIGTYPE_p_AssertionFailedException, 0), ":AssertionFailedException", SWIGTYPE_p_AssertionFailedException);
+This is useful when you want to pass the current exception object directly to Ruby, particularly when the object is an instance of class marked as an %exceptionclass (see the next section for more information).
+Last, you can raise an exception by directly calling Ruby's C api. This is done by invoking the rb_raise() function. The first argument passed to rb_raise() is the + exception type. You can raise a custom exception type or one of the built-in Ruby exception types.
+Starting with SWIG 1.3.28, the Ruby module supports the %exceptionclass directive, which is used to identify C++ classes that are used as exceptions. Classes that are marked with the %exceptionclass directive are exposed in Ruby as child classes of rb_eRuntimeError. This alows C++ exceptions to be directly mapped to Ruby exceptions, providing for a more natural integration between C++ code and Ruby code.
+ %exceptionclass CustomError;
+
+ %inline %{
+ class CustomError { };
+
+ class Foo {
public:
void test() { throw CustomError; }
+ };
+ }
+
+ From Ruby you can now call this method like this: +
foo = Foo.new +begin + foo.test() +rescue CustomError => e + puts "Caught custom error" +end+
For another example look at swig/Examples/ruby/exception_class.
+
@@ -1195,7 +1320,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
of using SWIG---the default wrapping behavior is enough in most cases. Typemaps
are only used if you want to change some aspect of the primitive C-Ruby
interface.
@@ -1262,7 +1387,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
puts Example.count('o','Hello World')
2
@@ -1319,7 +1444,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
Examples of these typemaps appears in the section
on typemap examples
$symname
@@ -1365,19 +1490,19 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
by David Thomas and Andrew Hunt.)
-
INT2NUM(long or int) - int to Fixnum or Bignum
INT2FIX(long or int) - int to Fixnum (faster than INT2NUM)
CHR2FIX(char) - char to Fixnum
rb_str_new2(char*) - char* to String
rb_float_new(double) - double to Float
int NUM2INT(Numeric)
int FIX2INT(Numeric)
unsigned int NUM2UINT(Numeric)
unsigned int FIX2UINT(Numeric)
long NUM2LONG(Numeric)
long FIX2LONG(Numeric)
unsigned long FIX2ULONG(Numeric)
char NUM2CHR(Numeric or String)
char * STR2CSTR(String)
char * rb_str2cstr(String, int*length)
double NUM2DBL(Numeric)
@@ -1392,7 +1517,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
RARRAY(arr)->ptr
@@ -1459,7 +1584,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
with the -w flag. The given format string fmt and remaining
arguments are interpreted as with printf().
-
@@ -1498,14 +1623,14 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
This section includes a few examples of typemaps. For more examples, you might look at the examples in the Example/ruby directory.
-
@@ -1529,7 +1654,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
allocation is used to allocate memory for the array, the "freearg" typemap is
used to later release this memory after the execution of the C function.
@@ -1642,7 +1767,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
the extension, can be found in the Examples/ruby/hashargs directory of
the SWIG distribution.
@@ -1689,7 +1814,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
%typemap(in) Foo * {
SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1);
}
@@ -1710,34 +1835,17 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
- SWIG allows operator overloading with, by using the %extend or %rename - commands in SWIG and the following operator names (derived from Python): -
-General-
__repr__ - inspect
__str__ - to_s
__cmp__ - <=>
__hash__ - hash
__nonzero__ - nonzero?
Callable
__call__ - call
Collection
__len__ - length
__getitem__ - []
__setitem__ - []=
Numeric
__add__ - +
__sub__ - -
__mul__ - *
__div__ - /
__mod__ - %
__divmod__ - divmod
__pow__ - **
__lshift__ - <<
__rshift__ - >>
__and__ - &
__xor__ - ^
__or__ - |
__neg__ - -@
__pos__ - +@
__abs__ - abs
__invert__ - ~
__int__ - to_i
__float__ - to_f
__coerce__ - coerce
Additions in 1.3.13
__lt__ - <
__le__ - <=
__eq__ - ==
__gt__ - >
__ge__ - >=
- Note that although SWIG supports the __eq__ magic method name for - defining an equivalence operator, there is no separate method for handling inequality - since Ruby parses the expression a != b as !(a == b). -
-- FIXME: This example is out of place here! -
-Another use for macros and type maps is to create a Ruby array from a STL vector +
FIXME: This example is out of place here!
+Another use for macros and type maps is to create a Ruby array from a STL vector of pointers. In essence, copy of all the pointers in the vector into a Ruby array. The use of the macro is to make the typemap so generic that any vector with pointers can use the type map. The following is an example of how to construct this type of macro/typemap and should give insight into constructing similar typemaps for other STL structures: -
+%define PTR_VECTOR_TO_RUBY_ARRAY(vectorclassname, classname)
%typemap(out) vectorclassname &, const vectorclassname & {
VALUE arr = rb_ary_new2($1->size());
vectorclassname::iterator i = $1->begin(), iend = $1->end();
for ( ; i!=iend; i++ )
rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i));
$result = arr;
}
%typemap(out) vectorclassname, const vectorclassname {
VALUE arr = rb_ary_new2($1.size());
vectorclassname::iterator i = $1.begin(), iend = $1.end();
for ( ; i!=iend; i++ )
rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i));
$result = arr;
}
%enddef
%define VECTOR_TO_RUBY_ARRAY(vectorclassname, classname)
%typemap(out) vectorclassname &, const vectorclassname & {
VALUE arr = rb_ary_new2($1->size());
vectorclassname::iterator i = $1->begin(), iend = $1->end();
for ( ; i!=iend; i++ )
rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, &(*i)));
$result = arr;
}
%typemap(out) vectorclassname, const vectorclassname {
VALUE arr = rb_ary_new2($1.size());
vectorclassname::iterator i = $1.begin(), iend = $1.end();
for ( ; i!=iend; i++ )
rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, &(*i)));
$result = arr;
}
%enddef
+ SWIG allows operator overloading with, by using the %extend or %rename + commands in SWIG and the following operator names (derived from Python): +
+General+
__repr__ - inspect
__str__ - to_s
__cmp__ - <=>
__hash__ - hash
__nonzero__ - nonzero?
Callable
__call__ - call
Collection
__len__ - length
__getitem__ - []
__setitem__ - []=
Numeric
__add__ - +
__sub__ - -
__mul__ - *
__div__ - /
__mod__ - %
__divmod__ - divmod
__pow__ - **
__lshift__ - <<
__rshift__ - >>
__and__ - &
__xor__ - ^
__or__ - |
__neg__ - -@
__pos__ - +@
__abs__ - abs
__invert__ - ~
__int__ - to_i
__float__ - to_f
__coerce__ - coerce
Additions in 1.3.13
__lt__ - <
__le__ - <=
__eq__ - ==
__gt__ - >
__ge__ - >=
+ Note that although SWIG supports the __eq__ magic method name for + defining an equivalence operator, there is no separate method for handling inequality + since Ruby parses the expression a != b as !(a == b). +
+The chapter on Working with Modules discusses the basics of creating multi-module extensions with SWIG, and in particular the considerations for sharing runtime type information among the different modules. -
+As an example, consider one module's interface file (shape.i) that defines our base class:
@@ -1836,83 +1960,8 @@ $ ruby -e 'puts $:.join("\n")'$ irb
irb(main):001:0> require 'shape'
true
irb(main):002:0> require 'circle'
true
irb(main):003:0> c = Circle::Circle.new(5, 5, 20)
#<Circle::Circle:0xa097208>
irb(main):004:0> c.kind_of? Shape::Shape
true
irb(main):005:0> c.getX()
5.0
- It's a fairly common practice in the Ruby built-ins and standard library to - provide aliases for method names. For example, Array#size is an alias - for Array#length. If you'd like to provide an alias for one of your - class' instance methods, one approach is to use SWIG's %extend directive - to add a new method of the aliased name that calls the original function. For - example: -
-class MyArray {
public:
// Construct an empty array
MyArray();
// Return the size of this array
size_t length() const;
};
%extend MyArray {
// MyArray#size is an alias for MyArray#length
size_t size() const {
return self->length();
}
}
- - A better solution is to instead use the %alias directive (unique to - SWIG's Ruby module). The previous example could then be rewritten as: -
-// MyArray#size is an alias for MyArray#length-
%alias MyArray::length "size";
class MyArray {
public:
// Construct an empty array
MyArray();
// Return the size of this array
size_t length() const;
};
- Multiple aliases can be associated with a method by providing a comma-separated - list of aliases to the %alias directive, e.g. -
-%alias MyArray::length "amount,quantity,size";-
- From an end-user's standpoint, there's no functional difference between these - two approaches; i.e. they should get the same result from calling either MyArray#size - or MyArray#length. However, when the %alias directive is - used, SWIG doesn't need to generate all of the wrapper code that's usually - associated with added methods like our MyArray::size() example. -
-Note that the %alias directive is implemented using SWIG's "features" - mechanism and so the same name matching rules used for other kinds of features - apply (see the chapter on "Customization - Features") for more details).
-- Predicate methods in Ruby are those which return either true or false. - By convention, these methods' names end in a question mark; some examples from - built-in Ruby classes include Array#empty? (which returns true - for an array containing no elements) and Object#instance_of? (which - returns true if the object is an instance of the specified class). For - consistency with Ruby conventions you would also want your interface's - predicate methods' names to end in a question mark and return true or false. -
-One cumbersome solution to this problem is to rename the method (using SWIG's %rename - directive) and provide a custom typemap that converts the function's actual - return type to Ruby's true or false. For example: -
-%rename("is_it_safe?") is_it_safe();
%typemap(out) int is_it_safe
"$result = ($1 != 0) ? Qtrue : Qfalse;";
int is_it_safe();
- - A better solution is to instead use the %predicate directive (unique - to SWIG's Ruby module) to designate certain methods as predicate methods. For - the previous example, this would look like: -
-%predicate is_it_safe();-
int is_it_safe();
and to use this method from your Ruby code:
-irb(main):001:0> Example::is_it_safe?-
true
- Note that the %predicate directive is implemented using SWIG's - "features" mechanism and so the same name matching rules used for other kinds - of features apply (see the chapter on "Customization - Features") for more details). -
-
@@ -1953,7 +2002,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
apply (see the chapter on "Customization
Features") for more details).
One of the most common issues in generating SWIG bindings for Ruby is proper
@@ -1972,7 +2021,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
versa) depending on what function or methods are invoked. Clearly, developing a
SWIG wrapper requires a thorough understanding of how the underlying library
manages memory.
Ruby uses a mark and sweep garbage collector. When the garbage collector runs,
@@ -1998,7 +2047,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
allocated in creating the underlying C struct or C++ struct, then a "free"
function must be defined that deallocates this memory.
As described above, memory management depends on clearly defining who is
@@ -2073,7 +2122,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
This code can be seen in swig/examples/ruby/tracking.
The remaining parts of this section will use the class library shown below to
@@ -2142,7 +2191,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
implement your own free functions (see below) you may also have to call theSWIG_RubyRemoveTracking
and RubyUnlinkObjects methods.
With a bit more testing, we see that our class library still has problems. For
@@ -2184,7 +2233,7 @@ $ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 /usr/
This code can be seen in swig/examples/ruby/mark_function.
-By default, SWIG creates a "free" function that is called when a Ruby object is