Version : SWIG 1.3.36
Repro steps:
1) Create a SWIG Ruby interface that uses std::vector for some type, e.g. Foo.
2) Specialize template via: %template (FooVector) std::vector<Foo>;
2) Build and attempt to load the extension
Actual result:
Load fails with an exception since the generated line in the method section for FooVector's wrapper code:
rb_define_alias(cFooVector.klass, "delete_if", "reject!")
This is because rb_define_alias is called _before_ rb_include_module(cFooVector.klass, cFooVector.mImpl) when multiple inheritance support is employed.
Expected result:
Loads correctly.
Notes:
This is a bug introduced during the Ruby STL upgrades between 1.3.31 and 1.3.36. The attached patch fixes the problem by moving the rb_include_module() call to the head of the wrapped function's init section. Note that it is perfectly acceptable to do the include operation in Ruby before methods are defined on the included module.
Patch for std::vector failure w/ -minherit
On rereading, my prose above about the problem ... is lacking. Let me try again: the issue is that rb_define_alias() is called on cFooVector.klass, but the "reject!" method isn't yet defined on that class since rb_include_module() hasn't been called yet. ("reject!" is defined on cFooVector.mImpl, under -minherit). Thus Ruby throws an exception on the rb_define_alias call since the target method doesn't exist.
I can't replicate the problem. Please supply a testcase. I've tried with the interface file below with
swig -c++ -ruby -minherit ../temp.i
// File: temp.i
%module temp
%include <std_vector.i>
%inline %{
struct Struct {
double num;
Struct() : num(0.0) {}
Struct(double d) : num(d) {}
};
struct Base1 {
};
struct MultipleDerived : Struct, Base1 {
};
%}
%template(VectMultipleDerived) std::vector<MultipleDerived>;
%inline %{
std::vector<MultipleDerived> vect_multiple_derived(std::vector<MultipleDerived> v) {
return v;
}
%}
and ruby code:
require 'temp'
include Temp
vmd = VectMultipleDerived.new()
vmd2 = vect_multiple_derived(vmd)
I can get a repro with the temp.i code; see below for excpetion. An key note: I'm interfacing with Ruby 1.8.7 p72. I'm building both Ruby and the SWIG extension with VC8 (VS2005), but I don't think that's relevant here since the issue appears to be Ruby API semantics, not the compilation environment.
>ruby -e 'require "temp"'
(eval): undefined method `reject!' for class `Temp::VectMultipleDerived' (NameError)
from -e:1
Again, with the patch provided, this code works as expected.
Thanks, replicated with ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]. I was about to commit this, but havn't as it has introduced a regression shown by the test-suite:
william@caracal:~/swig/trunk/Examples/test-suite/ruby$ make -s minherit.cpptest
checking testcase minherit (with run test) under ruby
./minherit_runme.rb:27: undefined method `xget' for #<Minherit::FooBar:0x40303e88> (NoMethodError)
make: *** [minherit.cpptest] Error 1
Can you take another look? I'm hoping to release 1.3.37 in a couple of days, so it will need urgent attention if it is to make the release.
Your patch didn't actually apply properly (probably the Windows file format), so I've attached a new patch which I was about to commit... it contains the new testcase.
File Added: ruby_minherit.patch
Bug 2048064 looks related to this one.
Ubuntu patch used instead: https://bugs.launchpad.net/ubuntu/+source/swig1.3/+bug/522874
Applied for swig-2.0.0
Another duplicate: 2962005