The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
=head1 NAME

Data::Context::Manual

=head1 SYNOPSIS

    # The config files (all produce the same data structures)
    # JSON relaxed : data.dc.js
    {
        # shell/perl style comments ok
        "PARENT": "other/path",
        "hash" : {
            "key" : "value", # allows trailing commas
            "action" : {
                "MODULE" : "My::Module",
                "METHOD" : "my_action",
            },
        },
    }

    # JSON strict : data.dc.json
    {
        "PARENT": "other/path",
        "hash" : {
            "key" : "value"
            "action" : {
                "MODULE" : "My::Module",
                "METHOD" : "my_action"
            }
        }
    }

    # YAML : data.dc.yml
    PARENT: other/path
    hash:
        key : value
        action:
            MODULE: My::Module
            METHOD: my_action

    # XML : data.dc.xml
    <config>
        <PARENT>other/path</PARENT>
        <hash>
            <key>value</key>
            <action>
                <MODULE>My:Module</MODULE>
                <METHOD>my_action</METHOD>
            </action>
        </hash>
    </config>

    # in perl
    use Data::Context;
    my $dc = Data::Context->new(
        path => [qw{ /path/one /paht/two }],
        fallback => 1,
        actions  => {
            do_something => sub { ... },
        },
    );
    my $data = $dc->get('data', { some => 'vars' });

=head1 DESCRIPTION

The power of L<Data::Context> is it's simple handling of many configuration
files. It supports configuration files in JSON format (strict & relaxed
variants), YAML and XML (via XML::Simple). Basically the aim is to support
any format that allows arbitrary depth data structures (eg not ini style files).

=head2 Inheritance

Each config file can specify a C<PARENT> config file, the raw data of the
parent file is merged (via L<Hash::Merge>) into the current config's raw
data. This is done recursively so the current config parent can itself
inherit another file. No checking is done circular references.

=head2 Variable substitutions

Config files may contain markers for data to be substituted the specified
position at run time.This consists of a dot separated list of hash keys or
array indexes surrounded by hashes (#).

 eg #my.path.3.value.0#

This would be the equivalent to accessing the data as

 $data->{my}{path}[3]{value}[0]

Checking is done along the path to access the data correctly, if an element
is a blessed object the path position will be attempted to be used as an
accessor.

 eg if my is an object
 $data->my->path()->[3]{value}[0]

If at any point in the expansion of the path no data is found undef is
returned for that value.

=head2 Actions

Variable expansion is actually a special case of an action. An action (in
the general form) is called by the config by specifying either C<METHOD>
and/or C<MODULE> keys.

If only C<METHOD> is specified the method is called against the C<action_class>
parameter of the L<Data::Context> object which by default is
L<Data::Context::Action>. Any actions passed into the L<Data::Context>
object are made available this way.

If only C<MODULE> is specified then the C<action_method> (by default get_data)
is used to call against C<MODULE>.

If both C<MODULE> and C<METHOD> are specified then C<MODULE>->C<METHID> is
used.

The contents of the hash containing C<MODULE> and/or C<METHOD> are passed to
the method, along with the C<vars> the request was called with, the dotted
path thought the config and a reference to the L<Data::Context::Instance>
object. The return value of the call is used to replace the original hash
value. That is unless the returned value is an L<AnyEvent::CondVar> variable.
If the result is a condvar then it will be recv()ed allowing for multiple
longer running events to occur. The result of the recv() (ie what is passed
to the ->send) is used to replace the original hash.

=head3 Ordering

The default order that actions are called is the reverse of the order that
they are encountered. This allows an action to include the output of
another action. If this ordering is not what the application requires, the
hash where the action is defined can specify C<ORDER> to overwrite the
default order. If C<ORDER> is a positive integer (including 0) then the
method will be called before other non ordered methods (but in increasing
numerical order by C<ORDER>). If the value is negative then it will be
run after all non ordered actions (again negative C<ORDER>s will be run in
increasing numerical order ie most negative to lease negative).

    eg data.dc.yml
    actions:
        -
            METHOD: get_unordered_second
        -
            METHOD: get_second
            ORDER: 1
        -
            METHOD: get_first
            ORDER: 0
        -
            METHOD: get_unordered_first
        -
            METHOD: get_last
            ORDER: -1
        -
            METHOD: get_last_but1
            ORDER: -2

    This will execute in order
        get_first
        get_second
        get_unordered_first
        get_unordered_second
        get_last_but1
        get_last

=head3 How Actions are called

=head3 NEW

Still to be implemented. Currently all method calls are class calls but the
C<NEW> key will be used to specify creating an object.

=head1 BUGS AND LIMITATIONS

There are no known bugs in this module.

Please report problems to Ivan Wills (ivan.wills@gmail.com).

Patches are welcome.

=head1 AUTHOR

Ivan Wills - (ivan.wills@gmail.com)

=head1 LICENSE AND COPYRIGHT

Copyright (c) 2012 Ivan Wills (14 Mullion Close, Hornsby Heights, NSW Australia 2077).
All rights reserved.

This module is free software; you can redistribute it and/or modify it under
the same terms as Perl itself. See L<perlartistic>.  This program is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

=cut