=pod

=head1 Classes and Objects

Many of Parrot's core classes -- such as C<Integer>, C<String>, or
C<ResizablePMCArray> -- are written in C, but you can also write your
own classes in PIR.  PIR doesn't have the shiny syntax of high-level
object-oriented languages, but it provides the necessary features to
construct well-behaved objects every bit as powerful as those of
high-level object systems.

X<objects>
Parrot developers often use the word "PMCs" to refer to the objects defined in
C classes and "objects" to refer to the objects defined in PIR. In truth, all
PMCs are objects and all objects are PMCs, so the distinction is a community
tradition with no official meaning.

=head2 Class Declaration

X<classes>
The C<newclass>X<newclass opcode> opcode defines a new class. It takes a
single argument, the name of the class to define.

=begin PIR_FRAGMENT

    $P0 = newclass 'Foo'

=end PIR_FRAGMENT

Just as with Parrot's core classes, the C<new>X<new opcode> opcode
instantiates a new object of a named class.

=begin PIR_FRAGMENT

  $P1 = new 'Foo'

=end PIR_FRAGMENT

In addition to a string name for the class, C<new> can also instantiate
an object from a class object or from a keyed namespace name.

=begin PIR_FRAGMENT

  $P0 = newclass 'Foo'
  $P1 = new $P0

  $P2 = new ['Bar';'Baz']

=end PIR_FRAGMENT

=head2 Attributes

X<attributes>
X<classes;attributes>
The C<addattribute> opcode defines a named attribute -- or I<instance variable> -- in the class:

=begin PIR_FRAGMENT

  $P0 = newclass 'Foo'
  addattribute $P0, 'bar'

=end PIR_FRAGMENT

The C<setattribute>X<setattribute> opcode sets the value of a declared
attribute.  You must declare an attribute before you may set it.  The value of
an attribute is always a PMC, never an integer, number, or string.N<Though it
can be an C<Integer>, C<Number>, or C<String> PMC.>

=begin PIR_FRAGMENT

    $P6 = box 42
    setattribute $P1, 'bar', $P6

=end PIR_FRAGMENT

The C<getattribute>X<getattribute opcode> opcode fetches the value of a
named attribute. It takes an object and an attribute name as arguments
and returns the attribute PMC:

=begin PIR_FRAGMENT

    $P10 = getattribute $P1, 'bar'

=end PIR_FRAGMENT

Because PMCs are containers, you may modify an object's attribute by retrieving
the attribute PMC and modifying its value.  You don't need to call
C<setattribute> for the change to stick:

=begin PIR_FRAGMENT

    $P10 = getattribute $P1, 'bar'
    $P10 = 5

=end PIR_FRAGMENT

=head2 Methods

X<methods>
X<classes;methods>
X<subroutines;methods>
Methods in PIR are subroutines stored in the class object. Define a method with
the C<.sub> directive and the C<:method>X<:method subroutine modifier> modifier:

=begin PIR

  .sub half :method
    $P0 = getattribute self, 'bar'
    $P1 = $P0 / 2
    .return($P1)
  .end

=end PIR

This method returns the integer value of the C<bar> attribute of the object
divided by two. Notice that the code never declares the named variable C<self>.
Methods always make the invocant object -- the object on which the method was
invoked -- available in a local variable called C<self>X<self variable>.

The C<:method> modifier adds the subroutine to the class object
associated with the currently selected namespace, so every class
definition file must contain a C<.namespace>X<.namespace directive>
declaration. Class files for languages may also contain an C<.HLL>X<.HLL
directive> declaration to associate the namespace with the appropriate
high-level language:

=begin PIR

  .HLL 'php'
  .namespace [ 'Foo' ]

=end PIR

Method calls in PIR use a period (C<.>) to separate the object from the method
name. The method name is either a literal string in quotes or a string
variable. The method call looks up the method in the invocant object using the
string name:

=begin PIR_FRAGMENT

    $P0 = $P1.'half'()

    $S2 = 'double'
    $P0 = $P1.$S2()

=end PIR_FRAGMENT

You can also pass a method object to the method call instead of looking it up
by string name:

=begin PIR_FRAGMENT

    $P2 = get_global 'triple'
    $P0 = $P1.$P2()

=end PIR_FRAGMENT

Parrot always treats a PMC used in the method position as a method object, so
you can't pass a C<String> PMC as the method name.

Methods can have multiple arguments and multiple return values just like
subroutines:

=begin PIR_FRAGMENT

  ($P0, $S1) = $P2.'method'($I3, $P4)

=end PIR_FRAGMENT

The C<can>X<can opcode> opcode checks whether an object has a particular
method. It returns 0 (false) or 1 (true):

=begin PIR_FRAGMENT

    $I0 = can $P3, 'add'

=end PIR_FRAGMENT

=head2 Inheritance

X<inheritance>
X<classes;inheritance>
The C<subclass>X<subclass opcode> opcode creates a new class that
inherits methods and attributes from another class. It takes two
arguments: the name of the parent class and the name of the new class:

=begin PIR_FRAGMENT

    $P3 = subclass 'Foo', 'Bar'

=end PIR_FRAGMENT

C<subclass> can also take a class object as the parent class instead of
a class name:

=begin PIR_FRAGMENT

    $P3 = subclass $P2, 'Bar'

=end PIR_FRAGMENT

X<multiple inheritance>
The C<addparent>X<addparent opcode> opcode also adds a parent class to a
subclass. This is especially useful for multiple inheritance, as
the C<subclass> opcode only accepts a single parent class:

=begin PIR_FRAGMENT

  $P4 = newclass 'Baz'
  addparent $P3, $P4
  addparent $P3, $P5

=end PIR_FRAGMENT

To override an inherited method in the child class, define a method with the
same name in the subclass. This example code overrides C<Bar>'s C<who_am_i>
method to return a more meaningful name:

=begin PIR

  .namespace [ 'Bar' ]

  .sub 'who_am_i' :method
    .return( 'I am proud to be a Bar' )
  .end

=end PIR

X<new opcode>
Object creation for subclasses is the same as for ordinary classes:

=begin PIR_FRAGMENT

    $P5 = new 'Bar'

=end PIR_FRAGMENT

Calls to inherited methods are just like calls to methods defined in
the class:

=begin PIR_FRAGMENT

    $P1.'increment'()

=end PIR_FRAGMENT

The C<isa> opcode checks whether an object is an instance of or inherits
from a particular class. It returns 0 (false) or 1 (true):

=begin PIR_FRAGMENT

    $I0 = isa $P3, 'Foo'
    $I0 = isa $P3, 'Bar'

=end PIR_FRAGMENT

=head2 Overriding Vtable Functions

X<overriding vtable functions>
X<vtable functions;overriding>
The C<Object> PMCX<Object PMC> is a core PMC written in C that provides
basic object-like behavior. Every object instantiated from a PIR class
inherits a default set of vtable functions from C<Object>, but you can
override them with your own PIR subroutines.

The C<:vtable>X<:vtable subroutine modifier> modifier marks a subroutine
as a vtable override. As it does with methods, Parrot stores vtable
overrides in the class associated with the currently selected namespace:

=begin PIR

  .sub 'init' :vtable
    $P6 = new 'Integer'
    setattribute self, 'bar', $P6
    .return()
  .end

=end PIR

Subroutines acting as vtable overrides must either have the name of an actual
vtable function or include the vtable function name in the C<:vtable> modifier:

=begin PIR

  .sub foozle :vtable('init')
    # ...
  .end

=end PIR

You must call methods on objects explicitly, but Parrot calls vtable functions
implicitly in multiple contexts.  For example, creating a new object with C<$P3
= new 'Foo'> will call C<init> with the new C<Foo> object.

As an example of some of the common vtable overrides, the C<=>X<=
operator> operator (or C<set>X<set opcode> opcode) calls C<Foo>'s
vtable function C<set_integer_native> when its left-hand side is a
C<Foo> object and the argument is an integer literal or integer
variable:

=begin PIR_FRAGMENT

    $P3 = 30

=end PIR_FRAGMENT

The C<+>X<+ operator> operator (or C<add>X<add opcode> opcode) calls
C<Foo>'s C<add> vtable function when it adds two C<Foo> objects:

=begin PIR_FRAGMENT

    $P3 = new 'Foo'
    $P3 = 3
    $P4 = new 'Foo'
    $P4 = 1774

    $P5 = $P3 + $P4
    # or:
    add $P5, $P3, $P4

=end PIR_FRAGMENT

The C<inc>X<inc opcode> opcode calls C<Foo>'s C<increment> vtable
function when it increments a C<Foo> object:

=begin PIR_FRAGMENT

    inc $P3

=end PIR_FRAGMENT

Parrot calls C<Foo>'s C<get_integer> and C<get_string> vtable functions to
retrieve an integer or string value from a C<Foo> object:

=begin PIR_FRAGMENT

    $I10 = $P5  # get_integer
    say $P5     # get_string

=end PIR_FRAGMENT

=head2 Introspection

X<introspection>
X<classes;introspection>
Classes defined in PIR using the C<newclass> opcode are instances of the
C<Class> PMCX<Class PMC>. This PMC contains all the meta-information for
the class, such as attribute definitions, methods, vtable overrides, and
its inheritance hierarchy. The opcode C<inspect>X<inspect opcode> 
provides a way to peek behind the curtain of encapsulation to see what
makes a class tick. When called with no arguments, C<inspect> returns an
associative array containing data on all characteristics of the class
that it chooses to reveal:

=begin PIR_FRAGMENT

  $P1 = inspect $P0
  $P2 = $P1['attributes']

=end PIR_FRAGMENT

When called with a string argument, C<inspect> only returns the data for
a specific characteristic of the class:

=begin PIR_FRAGMENT

  $P0 = inspect $P1, 'parents'

=end PIR_FRAGMENT

Table 7-1 shows the introspection characteristics supported by
C<inspect>.

=begin table Class Introspection

=headrow

=row

=cell Characteristic

=cell Description

=bodyrows

=row

=cell C<attributes>

=cell Information about the attributes the class will instantiate in
its objects. An associative array, where the keys are the attribute
names and the values are hashes of metadata.

=row

=cell C<flags>

=cell An C<Integer> PMC containing any integer flags set on the class
object.

=row

=cell C<methods>

=cell A list of methods provided by the class. An associative array
where the keys are the method names and the values are the invocable
method objects.

=row

=cell C<name>

=cell A C<String> PMC containing the name of the class.

=row

=cell C<namespace>

=cell The C<NameSpace> PMC associated with the class.

=row

=cell C<parents>

=cell An array of C<Class> objects that this class inherits from
directly (via C<subclass> or C<add_parent>). Does not include indirectly
inherited parents.

=row

=cell C<roles>

=cell An array of C<Role> objects composed into the class.

=row

=cell C<vtable_overrides>

=cell A list of vtable overrides defined by the class. An associative
array where the keys are the vtable names and the values are the
invocable sub objects.

=end table

=cut

# Local variables:
#   c-file-style: "parrot"
# End:
# vim: expandtab shiftwidth=4:
