

NAME
====

Joose.Manual.Reflection - The Joose reflection API


INTRODUCTION
============

Joose provides a powerful reflection API, which allows you fully introspect classes, attributes, methods, and so on.

These introspection methods are also handy if you want to generate docs or inheritance graphs, or do some other runtime reflection.

This document is currently not a complete reference for the introspection API. We're just going to cover some of the highlights, and give you a sense of how it all works. 
To really understand it, you'll have to read a other docs, or may be examine sources. 


GETTING STARTED
===============

The usual entry point to the meta API is through a class's metaclass instance, which is usually a `Joose.Meta.Class`. This is available by accessing the `meta` property on a class or instance:

        Class('User', {
            ...
        })
        
        var user = new User()
        
        var meta = User.meta
        -or-
        var meta = user.meta


USING THE METACLASS INSTANCE
============================

The metaclass instance can tell you about a class's attributes, methods, roles, parent, and more. For example, to scan through all of the class's attributes:

        meta.getAttributes().eachAll(function (attribute, name, isOwn) {
            console.log('class has attribute ' + name)
        })

The `getAttributes` method returns an instance of `Joose.Managed.PropertySet` class, which represents a set of attributes defined in the class (and its parent).

This instance provides an `eachAll` iterator, which will call a provided function for each element ('all' stands for: either defined in the class or in the superclass).

The 1st argument for iterator function will be usually an instance of "Joose.Managed.Attribute"
Note that sometimes it may actually be a subclass of `Joose.Managed.Attribute`, as Joose uses different classes to represent usual attribute, delegation attributes, etc.


You can also get a list of methods:

        meta.getMethods().eachAll(function (method, name, isOwn) {
            console.log('class has method ' + name)
        })

We receive an instance of `Joose.Managed.PropertySet.Containable` as well in this case.


ALTERING CLASSES
================

The metaclass object can change the class directly, by adding or removing attributes, methods, etc.

The recommended way is to call `extend` method of metaclass instance:

        meta.extend({
            has : {
                newAttribute : { is : 'rw', init : 'value' }
            }
        })

This way is guaranteed to produce consistent changes.


GOING FURTHER
=============

If you're interested in extending Joose, we recommend reading all of the "Meta" and "Extending" recipes in the [Joose.Cookbook][cookbook]. Those recipes show various practical applications of the metaclass API.

If you'd like to write your own extensions, one of the best ways to learn more about this is to look at other similar extensions to see how they work. 
You'll probably also need to read various API docs, including the docs for the various `Joose.Meta.*` classes.

Finally, we welcome questions on the Joose mailing list and IRC. Information on the mailing list, IRC, and more references can be found in the [Joose][joose] docs.


AUTHOR
======

Nickolay Platonov [nickolay8@gmail.com](mailto:nickolay8@gmail.com)

Heavily based on the original content of Moose::Manual, by Dave Rolsky [autarch@urth.org](mailto:autarch@urth.org)


COPYRIGHT AND LICENSE
=====================

Copyright (c) 2008-2011, Malte Ubl, Nickolay Platonov

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of Malte Ubl nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 

[cookbook]: ../Cookbook.html
[joose]: ../../Joose.html

