First, you are correct. The ruby generated Stuff::test
object is not of type Vectord
.
However, it is of a type that behaves exactly like Vectord
which is the most important question for a duck typed language like Ruby.
Correction to Stuff.i
There is one minor problem in your example. The %import <stl_vector.i>
statement should be %include <stl_vector.i>
.
The correct complete example is:
%module Stuff
%include "std_vector.i"
namespace std
{
%template(Vectord) vector<double>;
};
%inline%{
std::vector<double> test;
%}
Building the Module
The swig wrapper can be generated with
swig -ruby -c++ Stuff.i
And compiled (with g++) with the statement:
g++ Stuff_wrap.cxx -shared -fPIC -o Stuff.so -I /usr/lib/ruby/1.8/x86_64-linux/
Using the Module
jason@jason-VirtualBox:~$ irb
irb(main):001:0> require 'Stuff'
=> true
irb(main):003:0> Stuff::test.class
=> Array
As we can see, the object returned by Stuff::test
is of type Array
. However, unlike a regular Ruby array, this array can only be set to a value that is convertible to a std::vector<double>
irb(main):002:0> Stuff::test = [5,4,3]
=> [5, 4, 3]
irb(main):003:0> Stuff::test = [5.0, "5.0"]
TypeError: double
from (irb):3:in `test='
from (irb):3
from :0
Also, it can be converted directly to and from std::vector<double>
objects.
irb(main):002:0> vec = Stuff::Vectord.new()
=> std::vector<double,std::allocator< double > > []
irb(main):003:0> vec << 5.0
=> 5.0
irb(main):004:0> vec << 2.3
=> 2.3
irb(main):005:0> vec
=> std::vector<double,std::allocator< double > > [5.0,2.3]
irb(main):006:0> Stuff::test = vec
=> std::vector<double,std::allocator< double > > [5.0,2.3]
irb(main):007:0> vec2 = Stuff::Vectord.new(Stuff::test)
=> std::vector<double,std::allocator< double > > [5.0,2.3]
irb(main):008:0> Stuff::test.class
=> Array
irb(main):009:0> vec2.class
=> Stuff::Vectord
irb(main):010:0> Stuff::test
=> [5.0, 2.3]
Other SWIG Targets
It's important to note that the statically typed SWIG targets of C# and Java produce the results you were expecting. If you ever have a question about how your types are being handled in a SWIG output, it is almost always a good idea to compare the C# or Java output against what you are expecting.
Conclusion
While Stuff::test
and Vectord
are two different types, they both are arrays that can only store doubles.
They are almost indistinguishable inside of the Ruby code. The code produced does exactly what you want it to do.