From my Ruby C Extension I wanted to create a new Geom::Vector3d
instance from the Google SketchUp Ruby API: https://developers.google.com/sketchup/docs/ourdoc/vector3d
My initial code was this:
static inline VALUE
vector_to_sketchup( Point3d vector )
{
VALUE skp_vector, args[3];
args[0] = rb_float_new( vector.x );
args[1] = rb_float_new( vector.y );
args[2] = rb_float_new( vector.z );
skp_vector = rb_class_new_instance( 3, args, cVector3d );
}
This however raised an error:
Error: #<ArgumentError: wrong type - expected Sketchup::Vector3d>
Instead I had to call the ruby new
method - like so:
static inline VALUE
vector_to_sketchup( Point3d vector )
{
VALUE skp_vector;
skp_vector = rb_funcall( cVector3d, sNew, 3,
rb_float_new( vector.x ),
rb_float_new( vector.y ),
rb_float_new( vector.z )
);
return skp_vector;
}
I ran into the same problem with Geom::Point3d and Sketchup::Color.
rb_class_new_instance
is the preferred way to create a new instance in Ruby C, right?
Anyone got any idea why I needed to call new
? Some oddity with how the class was defined in SketchUp?
After communicating with the developers of Google SketchUp I have found the cause of this.
SketchUp makes use of Data_Wrap_Struct
to link their C classes with the Ruby classes. But they use an old method of allocating the data - which is within the #new
method.
In Ruby 1.8 you use rb_define_alloc_func()
to do the allocation and you never mess around with #new
. Ruby (1.6 and 1.8) defines #new
to call rb_class_new_instance()
.
Since I used rb_class_new_instance()
on SketchUp's old style classes the objects where not created properly, the allocation function was bypassed and never triggered. The error I got came from SketchUp, not Ruby.
So the answer is, you can use rb_class_new_instance()
to create new instances of classes provided they haven't overloaded the #new
method to do any initializations. Before Ruby 1.6 this was common for Ruby C classes if they needed to allocate data, but as of 1.8 it should be done with rb_define_alloc_func()
. (Matz says so here: https://web.archive.org/web/20131003102349/http://www.justskins.com/forums/the-new-allocation-scheme-132572.html#post437362 )
You can see the differences between Ruby 1.6 style and 1.8 style in this post: https://web.archive.org/web/20131003102349/http://www.justskins.com/forums/the-new-allocation-scheme-132572.html#post444948