see also: [ruby-object-lifecycle]
In Object Oriented programming sense, an object is a combination of data (state) and behaviour. Preferably combined in such a way that makes sense in the context of the program in which it lives.
In Ruby the body of an object is always expressed as a struct (one of the
members of the as
union in an RVALUE
that we talked about in
[rhg-garbage-collection] and [rvalue]).
A different struct will be used by each class but it will always be pointed to
by a VALUE
pointer.
Different structs used are:
struct RObject
all things for which none of the following appliesstruct RClass
class objectstruct RFloat
small numbersstruct RArray
arraystruct RRegexp
regular expressionstruct RHash
hash tablestruct RFile
IO
, File
, Socket
, etc…struct RData
all the classes defined at C level, except the ones mentioned abovestruct RStruct
Ruby’s Struct
classstruct RBignum
big integersBecause VALUE
is defined as unsigned long
it must be cast before being used
as a pointer. Macros exist for each object struct to cast value pointers to the
correct pointer type.
RSTRING(obj)->len; // ((struct RString*)obj)->len
Note: I was unfamiliar with the ->
syntax in C when I started looking at this.
it turns out it is broadly equivalent to the .
operator, ie it accesses a
member or calls a function. But it treats the caller as a pointer and
dereferences it first. so obj->bar
is the same as (*obj).bar
.
Every object struct contains an RBasic
as it’s first member (named basic
).
RBasic looks pretty much like this (and is defined in internal/core/rbasic.h
)
struct RBasic {
unsigned long flags;
VALUE klass;
}
flags
are multipurpose flags