# Slots

"Slots" are the name given to members of C++ classes that are available as
pseudo instance variables in the Ruby classes. For example,
vm/builtin/exception.hpp has the following member:

  private:
    String* message_;        // slot

In the Ruby Exception class, getting or setting @message will read or change
the value of message_ in the C++ class.

The // slot comment annotates the member as a slot. The annotation is
processed by vm/codegen/field_extract.rb to generate the glue code to make
this work.

In C++, all of the "slot" members are private. There are three macros used to
output getter and setter functions for the members.  These macros are named
after their Ruby analogues:

  attr_reader(name, Class);
  attr_writer(name, Class);
  attr_accessor(name, Class);

As in Ruby, attr_accessor is a combination of both attr_reader and
attr_writer. Again, looking in vm/builtin/exception.hpp, we see:

  public:
    /* accessors */
    attr_accessor(message, String);

The macro causes the following functions to be written:

  void message(STATE, String* obj) {
    message_ = obj;
    this->write_barrier(state, (OBJECT)obj);
  }
                                     }
  String* message() { return message_; }

See vm/builtin/object.hpp for the macro definitions.

Note that the name of the slot has a trailing `_' character.  External to the
C++ class, use the accessor functions to set and get the value of the "slot"
member. Internal to the class, you can use the member (e.g. message_)
directly.

If you set a slot declared as other than type OBJECT to Qnil, you will need to
cast the value you are passing. For example, to set message_ to Qnil, you need
to do the following:

  Exception* exc = ...
  exc->message(state, static_cast<String*>Qnil);

(The cast requirement will probably go away soon.)
