Enums¶
Rice supports both C enums and newer C++ enum classes.
enum Color
{ RED,
BLACK,
GREEN };
enum class Season
{ Spring,
Summer,
Fall,
Winter };
To expose an enum to Ruby, use define_enum
like this:
Enum<Color> colors = define_enum<Color>("Color")
.define_value("RED", RED)
.define_value("BLACK", BLACK)
.define_value("GREEN", GREEN);
define_enum<Color>("Color")
creates a new Ruby class called Color
. Each call to define_value
defines a new instance of Color that is stored as a constant on the Color class. Thus from the Ruby side of things, the mapping looks like:
class Color
RED = Color.new(RED)
BLACK = Color.new(BLACK)
GREEN = Color.new(GREEN)
end
Nested and Anonymous Enums¶
C/C++ supports the concept of anonymous enums. They used to be used as hack to define constants before C++ compilers supported member constants. For example:
class MyClass
{
public:
static const int SOME_CONSTANT = 42;
enum class Season
{ Spring,
Summer,
Fall,
Winter };
// Enum hack that used to be needed by compilers
enum
{
HACKED_CLASS_CONSTANT_1 = 43,
HACKED_CLASS_CONSTANT_2 = 44
};
};
In this case, there is one class enum and one anonymous enum. The anonymous enum should be mapped to static member constants like this:
// Define the class. Map anonymous enums to constants
Data_Type<MyClass> rb_cMyClass = define_class<MyClass>("MyClass").
define_constructor(Constructor<MyClass>()).
define_constant("SOME_CONSTANT", 42).
define_constant("HACKED_CLASS_CONSTANT_1", (int)MyClass::HACKED_CLASS_CONSTANT_1).
define_constant("HACKED_CLASS_CONSTANT_2", (int)MyClass::HACKED_CLASS_CONSTANT_2);
// Define the class and enum and nest it under MyClass
Enum<Season> seasons = define_enum_under<Season>("Season", rb_cMyClass)
.define_value("Spring", Season::Spring)
.define_value("Summer", Season::Summer)
.define_value("Fall", Season::Fall)
.define_value("Winter", Season::Winter);
From the Ruby side, this creates:
class MyClass
SOME_CONSTANT = 42
HACKED_CLASS_CONSTANT_1 = MyClass::HACKED_CLASS_CONSTANT_1
HACKED_CLASS_CONSTANT_2 = MyClass::HACKED_CLASS_CONSTANT_2
class Season
Spring = Color.new(Season::Spring)
Summer = Color.new(Season::Summer)
Fall = Color.new(Season::Fall)
Winter = Color.new(Season::Winter)
end
end
Ruby API¶
Generated enum classes have the following Ruby API.
Enum.from_int
Enum#<=>
Enum#eql?
Enum#hash
Enum#each
Enum#inspect
Enum#to_int
Enum#to_s
Enum#&
Enum#|
Enum#^
Enum#~
Enum#<<
Enum#>>
In addition, they have the following aliases:
Enum#===
Enum#eql?
Enum#to_i
Enum#to_int
And mixin the following modules: