NAME

Clownfish::Docs::ClassIntro - Working with Apache Clownfish classes in C

DESCRIPTION

Inititalizing Clownfish parcels

Every Clownfish parcel must be initialized before it is used. The initialization function is named {parcel_nick}_bootstrap_parcel and takes no arguments.

Example:

cfish_bootstrap_parcel();

Including the generated header file

To use Clownfish classes from C code, the header file generated by the Clownfish compiler must be included. The name of the C header is derived from the name of the Clownfish .cfh header. It can also be found in the class documentation.

Typically, the “short name macro” should be defined before including a Clownfish header. Its name is derived from the parcel nickname and has the form {PARCEL_NICK}_USE_SHORT_NAMES. If the short name macro is in effect, you don’t have to worry about parcel prefixes.

Example:

#define CFISH_USE_SHORT_NAMES

#include <Clownfish/String.h>
#include <Clownfish/Vector.h>

Function and method prefixes

Clownfish classes can have a “nickname” – a shorter version of the class name that is used for function and method prefixes. The nickname can be found in the class documentation.

For example the String class has the nickname Str.

Creating objects

A Clownfish object is an opaque struct referenced by pointer.

Most classes come with one or more constructors. On the C level, a constructor is simply an “inert” function of a class that returns a new object. In Clownfish parlance, an inert function is any function in a class that isn’t a method, similar to static methods in Java or static member functions in C++.

Example:

// Notice the use of nickname "Str" in the constructor prefix.
String *name = Str_newf("%s %s", first, last);

Calling methods

Calling methods is straightforward. The invocant is always passed as first argument.

// Notice the use of nickname "Str" in the method prefix.
size_t len = Str_Length(name);

Method names always start with an uppercase letter.

Memory management

Clownfish uses reference counting to manage memory. Constructors, but also some methods, return an “incremented” object. If you’re done with an incremented object, you must decrease its reference count to avoid leaking memory. Use the DECREF macro to release an object:

DECREF(name);

Some other methods return non-incremented objects. If you want to retain a reference to such an object, you must increase its reference count using the INCREF macro to make sure it won’t be destroyed too early:

obj = INCREF(obj);

This invocation of INCREF must be matched by a DECREF when you’re done with the object.

Some methods, for example in container classes, take “decremented” objects as arguments. From the caller’s perspective, passing a decremented argument is equivalent to passing a non-decremented argument and calling DECREF afterwards. Typically, this avoids a call to DECREF in the calling code. But sometimes, it must be compensated with an INCREF.

Further reading