/** @page builtin_object_creation_in_c++.txt

 Object Creation in C++
========================

Concerning creating objects of the builtin classes in Rubinius (i.e.
classes existing in `vm/builtin/`.) Internal-only objects do not use
this model.


 Ruby Model
------------

In Ruby, objects are created in two ways: using `.allocate` or `.new`.
`.allocate` gives an "empty" object that is fully functional, but has
not been set up with any specific information. In order to create an
object that has been set up with such information, `.new` is used. It
first calls `.allocate` to obtain the "empty" object, after which it
calls the object's instance method `#initialize`, passing along any
arguments and block that it received. Essentially:

    def self.new(*args, &block)
      obj = self.allocate
      obj.initialize *args, &block
      return obj
    end


 C++ Conceptually
------------------

The Rubinius C++ API works analogously to the two Ruby methods. The
class method `allocate` is exactly equivalent to the Ruby `.allocate`
and actually implements the primitive for the latter. So if one were
to call `allocate` for some class in C++, they would get the same
fully functional but non-initialized object. In practice, there is
probably no reason to ever call `allocate` in C++.

The `create` class method is the equivalent of `.new` in Ruby. It
may take arguments using which it will initialize the basic object
it has `allocate`d. The only difference to Ruby is that there is
no separate `initialize` instance method: all the initialization
is done inside `create` directly.


 C++ in Practice
-----------------

All the C++ methods take the VM state as their first argument. The
short explanation is that passing the state explicitly removes the
need to use a global state. To simplify the illustration, it has
been omitted here, but e.g. `allocate()` really is `allocate(STATE)`.

In order to ensure that there is no duplication of code and/or logic,
the C++ `allocate()` is actually defined in terms of `create()`. To
be precise, in C++ the call to `allocate()` is a call to `create()`
with no arguments. The `create()` method may employ default arguments,
so long as it can be called with an empty argument list (except of
course STATE which we pretend does not really exist.) `create()`
may be overloaded as desired so long as there is one version that
can be called without arguments.


 Restrictions
--------------

In order to avoid unnecessary confusion,

* Builtins must not implement `initialize()`.
* Builtins must not implement a C++ constructor.

*/
