Ruby does not have an enumerated type, so the Slice enumerations are emulated using a Ruby class: the name of the Slice enumeration becomes the name of the Ruby class; for each enumerator, the class contains a constant with the same name as the enumerator (see
Section 26.3 for more information on identifiers). For example:
The compiler generates a class constant for each enumerator that holds a corresponding instance of
Fruit. The
from_int class method returns an instance given its integer value, while
to_i returns the integer value of an enumerator and
to_s returns its Slice identifier. The comparison operators are available as a result of including
Comparable, which means a program can compare enumerators according to their integer values.
Slice structures map to Ruby classes with the same name. For each Slice data member, the Ruby class contains a corresponding instance variable as well as accessors to read and write its value. For example, here is our
Employee structure from
Section 4.9.4 once more:
The constructor initializes each of the instance variables to a default value appropriate for its type. You can also declare different default values for members of primitive and enumerated types, as discussed in
Section 4.9.2.
The compiler generates a definition for the hash method, which allows instances to be used as keys in a hash collection. The
hash method returns a hash value for the structure based on the value of its data members.
The == method returns true if all members of two structures are (recursively) equal.
The inspect method returns a string representation of the structure.
Slice sequences map to Ruby arrays; the only exception is a sequence of bytes, which maps to a string (see below). The use of a Ruby array means that the mapping does not generate a separate named type for a Slice sequence. It also means that you can take advantage of all the array functionality provided by Ruby. For example:
The Ice run time validates the elements of a sequence to ensure that they are compatible with the declared type; a
TypeError exception is raised if an incompatible type is encountered.
A Ruby string can contain arbitrary 8‑bit binary data, therefore it is a more efficient representation of a byte sequence than a Ruby array in both memory utilization and throughput performance.
When receiving a byte sequence (as the result of an operation, as an out parameter, or as a member of a data structure), the value is always represented as a string. When sending a byte sequence as an operation parameter or data member, the Ice run time accepts both a string and an array of integers as legal values. For example, consider the following Slice definitions:
The two invocations of sendData are equivalent; however, the second invocation incurs additional overhead as the Ice run time validates the type and range of each array element.
As for sequences, the Ruby mapping does not create a separate named type for this definition. Instead,
all dictionaries are simply instances of Ruby’s hash collection type. For example:
The Ice run time validates the elements of a dictionary to ensure that they are compatible with the declared type; a
TypeError exception is raised if an incompatible type is encountered.