Migrating from 3 to 4#
Prior versions of Rice required compiling some initial code on gem install
. This has made Rice and libraries that use Rice to be difficult to use on some platforms, such as Heroku or Github Actions, where
where the appropriate shared libraries and/or build systems are not allowed or available.
Rice 4 transitions to being a header only library, making it much easier for libraries using Rice to provide binary builds. However, this work was substantial and required making a few backwards-incompatible changes This page documents the major changes that any one using Rice 3 will need to apply to their libraries to work with Rice 4 or newer.
#include <rice/rice.hpp>#
The first change is that Rice is now published as a single, combined header file, so all includes can be changed to just this one. There is one other header file that contains STL wrapper definitions, you can get that with #include <rice/stl.hpp>
. For more information see the STL section.
to_ruby / from_ruby#
The most notable backwards-incompatible change is how you define Ruby <=> C++ type conversions.
In Rice 3, you defined the methods to_ruby
and from_ruby
like this:
template<>
Foo from_ruby<Foo>(Rice::Object x)
{
// ...
}
template<>
Rice::Object to_ruby<Foo>(Foo const & x)
{
// ...
}
In Rice 4, the structure of these functions has changed significantly. You now define these methods
as a convert
function in a struct, and they need to live in the Rice::detail
namespace:
namespace Rice::detail
{
template<>
class From_Ruby<Foo>
{
Foo convert(VALUE x)
{
// ...
}
};
template<>
class To_Ruby<Foo>
{
VALUE convert(Foo const & x)
{
// ...
}
};
}
In addition, they work with Ruby’s VALUE type as opposed to Rice’s Object type. This switch was made to avoid making extra copies of objects when translating between C++ and Ruby. For more information, please refer to the type conversion section.
Functions vs Methods#
Rice now has different define_
methods depending on if you are defining a method on an object or
a normal function. If you need self
, use define_method
or define_singleton_method
. Otherwise
you should use define_function
and define_singleton_function
. You can read more in the tutorial.
Default Arguments#
They way Rice defines C++ Default Arguments has subtly changed - this is an easy one to miss and can introduce bugs (default values will not be set correctly). Previously Rice relied on C++’s comma operator to combine arguments together:
define_method("hello", &Test::hello, (Arg("hello"), Arg("second") = "world"));
Notice that the two Args
are surrounded by parentheses. Rice no longer support this style. Instead, just pass the Args
in a more natural way without the parentheses:
define_method("hello", &Test::hello, Arg("hello"), Arg("second") = "world");
Memory Management#
Rice 4 also requires and provides more tools for explicitly defining which objects should and should not be managed by the Ruby garbage collector. Read more in Memory Management.