NAME ^

src/pmc/class.pmc - defines a class

DESCRIPTION ^

This class implements the Class PMC, as outlined in docs/pdds/pdd15_objects.pod.

Class is not derived from any other PMC.

Structure ^

The Role PMC structure (Parrot_Role) consists of five items:

name

The name of the class -- a STRING. An empty STRING is allocated during initialization.

namespace

The namespace the class is associated with, if any. A Null PMC is allocated during initialization.

instantiated

A flag denoting whether this class has been instantiated since last modification. A native integer with value zero is allocated during initialization.

parents

An array of immediate parent classes. An empty ResizablePMCArray PMC is allocated during initialization.

all_parents

A cached array of ourself and all parent classes, in MRO order. A ResizablePMCArray PMC is allocated during initialization, and is populated with the current class.

roles

An array of the roles this class has been composed from. An empty ResizablePMCArray PMC is allocated during initialization.

methods

A directory of method names and method bodies this class provides. An empty Hash PMC is allocated during initialization.

vtable_methods

A directory of vtable method names and method bodies this class overrides. An empty Hash PMC is allocated during initialization.

attrib_metadata

A directory of attribute names and attribute metadata this class contains. An empty Hash PMC is allocated during initialization.

attrib_index

A lookup table for attributes in this class and parents. A Null PMC is allocated during initialization.

attrib_cache

A cache of visible attribute names to attribute indexes. A Null PMC is allocated during initialization.

resolve_method

A list of method names the class provides used for name conflict resolution. An empty ResizablePMCArray PMC is allocated during initialization.

Functions ^

void init()

Initializes a Class PMC.

void init_pmc(PMC *name)

The actual class creation code, called from newclass opcode. The init argument must stringify to the name of the class. The class is attatched to the current namespace.

PMC *subclass(PMC *name)

Creates a subclass, optionally with a given name.

void destroy()

Free the memory associated with the object's underlying struct.

STRING *get_string()

Return the fully qualified name of the class.

void mark()

Mark any referenced strings and PMCs in the structure as live.

void add_attribute(STRING *name, PMC *type)

Adds the given attribute (name) with an optional type. Creates a new class if the current class has been instantiated. Enters the attribute in the attributes array. Returns an error if an attribute of name already exists.

void add_method(STRING *name, PMC *sub)

Adds the given sub PMC as a method with the given name.

void add_parent(PMC *parent)

Adds the supplied PMC to the list of parents for the class.

void add_role(PMC *role)

Adds the supplied PMC to the list of roles for the class, provided there are no conflicts.

PMC *inspect_str(STRING *what)

Provides introspection of a specific piece of information about the class. The available information is:

name

String PMC containing the name of the class

namespace

NameSpace PMC of the the namespace attached to the class

attributes

Hash keyed on attribute name, value is hash describing it

methods

Hash keyed on method name, value is an invokable PMC. Includes methods composed in from roles.

roles

Array of Role PMCs. Includes roles done by the roles that were composed into this class.

parents

Array of Class PMCs representing the direct parents of this class.

PMC *inspect()

Returns a Hash describing the class, with key/value pairs as described in inspect_str.

PMC *clone()

Returns an anonymous copy of the class (with no name and no link to a namespace). Unsets the instantiated flag, allowing modifications.

PMC *clone_pmc(PMC *args)

Makes a copy of the class, then modifies or adds to it based upon the contents of the supplied initialization data. If a new name or namespace is not supplied in args then the cloned class will be anonymous. The instantiated flag is unset to allow further modifications.

INTVAL isa(STRING *classname)

Returns whether the class is or inherits from *classname.

void name(STRING *name :optional, int got_name :opt_flag)

Sets the name of the class, and updates the namespace accoringly.

void pmc_namespace()

Gets the namespace that this class is attached to.

void resolve_method()

Sets the list of method names that the class provides to resolve conflicts in methods from roles. When called with no parameter, returns the list.

void new(PMC *args :slurpy :named)

Creates an instance of the object. Initializes any attributes specified in the parameter list.

void attributes()

Return a hash where the keys are attribute names and the values are hashes providing a set of key/value pairs describing the attribute.

void add_attribute()

Add an attribute to the class. Requires a name and, optionally, a type.

void methods()

Return a hash where the keys are method names and the values are methods.

void add_method(STRING *name, PMC *sub)

Adds the given sub PMC as a method with the given name. Delegates to the add_method vtable method.

PMC *find_method(STRING *name)

Walks the MRO of the class and finds the method with the given name.

*/

    PCCMETHOD void find_method(STRING *name) {
        Parrot_Class * const  _class    = PARROT_CLASS(SELF);
        PMC                  *namespace = _class->_namespace;
        int num_classes, i;

        if (  ! PMC_IS_NULL(namespace)
            &&  VTABLE_exists_keyed_str(interp, namespace, name)) {
            PMC *ret = VTABLE_get_pmc_keyed_str(interp, namespace, name);
            PCCRETURN(PMC *ret);
        }

        /* Walk and search. One day, we'll use the cache first. */
        num_classes = VTABLE_elements(interp, _class->all_parents);

        for (i = 0; i < num_classes; i++) {
            /* Get the class and see if it has the method. */
            PMC * const cur_class =
                VTABLE_get_pmc_keyed_int(interp, _class->all_parents, i);
            const Parrot_Class * const class_info = PARROT_CLASS(cur_class);

            /* Found it! */
            if (VTABLE_exists_keyed_str(interp, class_info->methods, name)) {
                PMC *ret = VTABLE_get_pmc_keyed_str(interp, class_info->methods,
                    name);
                PCCRETURN(PMC *ret);
            }
        }

        PCCRETURN(PMC *PMCNULL);
    }
/*

void parents()

Return the parents array PMC.

void add_parent(PMC *parent)

Adds the supplied PMC to the list of parents for the class.

void roles()

Return the roles array PMC.

void add_role(PMC *role, PMC *exclude :optional :named["exclude"], PMC *alias :optional :named["alias"])

Compose a role into a class with the given exclusions and aliases.

void inspect(STRING *what :optional)

Gets all introspection data for the class or, if the optional string parameter is supplied, a particular item of introspection data.

void isa(STRING *class_name)

Returns true if this object is or derives from the class named in class_name, false otherwise.

void does(STRING *role_name)

Returns true if this object or one of its parents performs the named role, false otherwise.

SEE ALSO ^

docs/pdds/pdd15_objects.pod.


parrot