#88 shared_ptr support for Ruby and Perl

open
nobody
None
5
2013-02-16
2012-11-09
Tim Jensen
No

Ruby and Perl support for shared_ptr (std and boost) would be extremely helpful.

Discussion

  • Tim Jensen
    Tim Jensen
    2013-02-16

    I'm adding a little clarification because I know the documentation does mention "smart pointer" support for Ruby at http://swig.org/Doc2.0/Ruby.html#Ruby_nn24.

    In Ruby, the current support for shared_ptr in SWIG 2.0.9 falls short in a few ways:

    • Empty shared_ptr objects are not automatically converted to nil.
    • When class U derives from class T, a shared_ptr<U> does not get automatically up-cast
      to a shared_ptr<T>.
    • When passed as parameters, shared_ptr<T> objects are not automatically converted to T when the function signature requires it.

    I have attached some sample code which compares SWIG Python behavior to SWIG Ruby behavior though a series of unit tests in each language. These Ruby tests demonstrate the shortcomings listed above. The Python tests show the expected behavior. A Makefile is provided to simplify building and running the tests on Linux (I used Ubuntu 12.04LTS to develop the sample code). Run "make ruby" to run the Ruby unit tests. Run "make python" to run the Python unit tests.

     
  • Tim Jensen
    Tim Jensen
    2013-02-16

    BTW, I have had partial success working around the empty-shared_ptr-as-nil issue by adding "out" typemaps along similar to:

    %typemap(out) boost::shared_ptr< CONST TYPE >
    %{
        $result = $1 ? SWIG_NewPointerObj( /* ... */ ) : Qnil;
    %}
    

    This helps in most cases, but I have noticed that the order of %template directives can prevent the typemaps from being used in some situations. Using the sample code I attached in my previous comment, for example:

    o = Thingy::Other.create  # o is a shared_ptr
    b = o.base(false)         # b _should_ be nil
    b.doof unless b.nil?      # Crash because b is an empty shared_ptr
    

    Moving the %template directives for shared_ptr<Other> to after the ones for shared_ptr<Base> and shared_ptr<Derived> seems to fix the issue but ensuring correct ordering when you have many classes is very difficult.