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