The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


Role::TinyCommons::Tree::FromStruct - Role that provides methods to build tree object from data structure


This document describes version 0.129 of Role::TinyCommons::Tree::FromStruct (from Perl distribution RoleBundle-TinyCommons-Tree), released on 2021-10-07.




new_from_struct($struct) => obj

Construct a tree object from a data structure $struct. The data structure must be a hash. Its keys must contain zero or more attributes to set the attributes of the to-be-created tree node. Keys that begin with underscore (_), however, contains special instructions.

Example usage:

 my $family_tree = My::Person->new_from_struct({
     name => 'Andi', age => 64, _children => [
         {name => 'Budi', age => 30},
         {name => 'Cinta', _class => 'My::MarriedPerson', _children => [
              {name => 'Deni'},
              {name => 'Eno'},

In this example, new_from_struct will create the first (root) node using:

 My::Person->new(name => 'Andi', age => 64)

To customize how a node is instantiated, there are several ways. First, if you want to use another class, you can put a _class key in your struct, e.g. _class => 'My::MarriedPerson'. Node will then be created using:

 My::MarriedPerson->new(name => 'Andi', age => 64)

If your constructor method name is not new, you can set that using the _constructor key.

If your constructor does not accept a list of attribute name and value pairs, but a hash(ref) of attributes, you can set _pass_attributes to hashref, and then node will be created using:

 My::Person->new({ name => 'Andi', age => 64 })

Or, if your constructor doesn't take any argument and the attributes are set using individual accessor methods, you can set the _pass_attributes key to false and then node will be created using:

 do {
     my $node = My::Person->new;

Finally, if you need total customization for the constructor and initialization of your node, you can supply the key _instantiate instead. This should be a code that instantiate your node. The code will be passed ($class, \%attrs) and should return the newly created node. Example:

 _instantiate => sub {
     my ($class, $attrs) = @_;
     $class->create_person($attrs->{name}, $attrs->{age} // 0);

The _children key (arrayref of structs) instructs how to create children nodes. This will recursively call new_from_struct for each child. The parent's _constructor, _pass_attributes, and _instantiate keys will be set as the default for the child's struct, but of course child can override it should they want to.

Finally, the children will be connected to their parents and vice versa. And the final tree object (root node) is returned.

Continuing from the previous example:

 my $family_tree = My::Person->new_from_struct({
     name => 'Andi', age => 64, _children => [
         {name => 'Budi', age => 30},
         {name => 'Cinta', _class => 'My::MarriedPerson', _children => [
              {name => 'Deni'},
              {name => 'Eno'},

Here are the steps that will be performed (so in essence what new_from_struct provides is convenience of not having to connect parent and children nodes manually):

 my $andi = My::Person->new(name => 'Andi', age => 64);

 my $budi  = My::Person->new(name => 'Budi', age => 30);

 my $cinta = My::MarriedPerson->new(name => 'Cinta');

 $andi->children([$budi, $cinta]);

 # class defaults back to My::Person since _class is not specified and not
 # passed down to children's struct

 my $deni = My::Person->new(name => 'Deni');

 my $eno = My::Person->new(name => 'Eno');

 $cinta->children([$deni, $eno]);



Please visit the project's homepage at


Source repository is at


Code::Includable::Tree::FromStruct if you want to use the routines in this module without consuming a role.

Role::TinyCommons::Tree::FromObjArray if you want to build a tree of objects from a nested array of objects.




perlancar <>


To contribute, you can send patches by email/via RT, or send pull requests on GitHub.

Most of the time, you don't need to build the distribution yourself. You can simply modify the code, then test via:

 % prove -l

If you want to build the distribution (e.g. to try to install it locally on your system), you can install Dist::Zilla, Dist::Zilla::PluginBundle::Author::PERLANCAR, and sometimes one or two other Dist::Zilla plugin and/or Pod::Weaver::Plugin. Any additional steps required beyond that are considered a bug and can be reported to me.


This software is copyright (c) 2021, 2020, 2016 by perlancar <>.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.


Please report any bugs or feature requests on the bugtracker website

When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature.