Forest::Tree::Constructor - An abstract role for tree factories


Forest documentation Contained in the Forest distribution.

Index


Code Index:

NAME

Top

Forest::Tree::Constructor - An abstract role for tree factories

SYNOPSIS

Top

    with qw(Forest::Tree::Constructor);

    sub tree_class { ... }

    sub foo {
        $self->create_new_subtree( ... )
    }

DESCRIPTION

Top

This role provides the create_new_subtree method as required by Forest::Tree::Builder and Forest::Tree::Loader/Forest::Tree::Reader.

See Forest::Tree::Builder for the reccomended usage.

BUGS

Top

All complex software has bugs lurking in it, and this module is no exception. If you find a bug please either email me, or add the bug to cpan-RT.

AUTHOR

Top

Yuval Kogman

COPYRIGHT AND LICENSE

Top


Forest documentation Contained in the Forest distribution.

package Forest::Tree::Constructor;
use Moose::Role;

our $VERSION   = '0.09';
our $AUTHORITY = 'cpan:STEVAN';

requires "tree_class";

sub create_new_subtree {
    my ($self, %options) = @_;
    my $node = $options{node};

    if (blessed($node) && $node->isa('Forest::Tree::Pure')) {
        # when node is an tree object we assume that it's a prototype of a tree
        # node to be filled in

        # remove meaningless keys
        delete $options{node};
        delete $options{children} if exists $options{children} and not @{ $options{children} };

        # nothing left to be done if the option cleanup deleted all keys
        return $node unless keys %options;

        if ( $node->child_count == 0 ) {
            if ( $node->isa("Forest::Tree") ) {
                # mutable trees get modified

                foreach my $key ( keys %options ) {
                    $node->$key( $options{$key} );
                }

                return $node;
            }
            else {
                # pure trees get cloned
                return $node->clone(%options);
            }
        }
        else {
            # i suppose $options{children} could be appended to $node->children
            # if there are any, but that doesn't really make sense IMHO, might
            # as well write your own builder at that point instead of kludging
            # it with the parser callback for the simple text loader or something
            confess("Can't override children from proto node");
        }
    }
    else {
        return $self->tree_class->new(%options);
    }
}


# ex: set sw=4 et

no Moose::Role; 1;

__END__