Forest...::Pure(3pm)

πŸ“¦
version 0.10 Β· 2 versions
  • 0.10 Β· debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking (latest)
  • 0.10 Β· ubuntu jammy
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

πŸ’– Forest::Tree::Pure πŸ’–

okay bestie, welcome to Forest::Tree::Pure(3pm) β€” part of the User Contributed Perl Documentation, and literally one of my faves. it's the n-ary tree module. let's get into it πŸŽ€


✨ NAME ✨

Forest::Tree::Pure β€” An n-ary tree 🌳


✨ SYNOPSIS ✨

okay so, no cap, here's the vibe:

  use Forest::Tree;

  my $t = Forest::Tree::Pure->new(
      node     => 1,
      children => [
          Forest::Tree::Pure->new(
              node     => 1.1,
              children => [
                  Forest::Tree::Pure->new(node => 1.1.1),
                  Forest::Tree::Pure->new(node => 1.1.2),
                  Forest::Tree::Pure->new(node => 1.1.3),
              ]
          ),
          Forest::Tree::Pure->new(node => 1.2),
          Forest::Tree::Pure->new(
              node     => 1.3,
              children => [
                  Forest::Tree::Pure->new(node => 1.3.1),
                  Forest::Tree::Pure->new(node => 1.3.2),
              ]
          ),
      ]
  );

  $t->traverse(sub {
      my $t = shift;
      print(('    ' x $t->depth) . ($t->node || '\undef') . "\n");
  });

she walks the whole tree and prints it out with cute lil indents, we love to see it πŸ’…


✨ DESCRIPTION ✨

so this module is a base class for Forest::Tree, and it brings the functionality for immutable trees. it's giving "you can look, you can't touch" πŸ”₯

you can also use it all on its own, for trees where you need to share children between parents.

here's the thing though β€” there is no single authoritative parent (no upward links at all, zero, nada), and changing of data is not supported. periodt.

this class is the one you want when many tree roots share the same children β€” e.g. in a versioned tree. iconic behavior honestly.

and like, important detail: this class is strictly a DAG, wheras Forest::Tree produces a graph with back references. (yes, "wheras", I'm quoting, don't come for me 😭)


✨ ATTRIBUTES ✨

πŸ¦‹ node

πŸ¦‹ children

  • get_child_at ($index) β€” returns the child at this position. (zero-base index, so like, first one is 0, iykyk)
  • child_count β€” returns the number of children this tree has 🍼

πŸ¦‹ size

  • size
  • has_size

πŸ¦‹ height

  • height
  • has_height

✨ METHODS ✨

🌸 is_leaf

true if the current tree has no children. baby tree, no descendants, just vibes πŸƒ

🌸 traverse (\&func)

takes a reference to a subroutine and traverses the tree applying this subroutine to every descendant. (But not the root) β€” heads up bestie, the root does NOT get visited here, she's excluded 😀

🌸 visit (&func)

traverse the entire tree, including the root. so yeah, this one's the full package 🫢

🌸 fmap_cont (&func)

a CPS form of "visit" that lets you control when and how data flows from the children. main character energy, you're driving πŸš—

it takes a callback in the form:

  sub {
      my ( $tree, $cont, @args ) = @_;

      ...
  }

and $cont is a code ref that when invoked will apply that same function to the children of $tree.

this allows you to do things like computing the sum of all the node values in a tree, for instance:

  use List::Util qw(sum);

  my $sum = $tree->fmap_cont(sub {
      my ( $tree, $cont ) = @_;

      return sum( $tree->node, $cont->() );
  });

and also allows one to stop traversal at a given point. you can just dip whenever, obsessed βœ‹

🌸 add_children (@children)

🌸 add_child ($child)

create a new tree node with the children appended.

the children must inherit "Forest::Tree::Pure" β€” so keep it in the family pls πŸ’œ

note that this method does not mutate the tree, instead it clones and returns a tree with the augmented list of children. no take-backs, no side effects, immaculate 🌈

🌸 insert_child_at ($index, $child)

insert a child at this position. (zero-base index)

returns a derived tree with overridden children.

🌸 set_child_at ($index, $child)

replaces the child at $index with $child. swap 'em out bestie πŸ”„

🌸 remove_child_at ($index)

remove the child at this position. (zero-base index)

returns a derived tree with overridden children.

🌸 locate (@path)

find a child using a path of child indexes. these two examples return the same object:

  $tree->get_child_at(0)->get_child_at(1)->get_child_at(0);

  $tree->locate(0, 1, 0);

same destination, way less typing. we stan a shortcut ✨

🌸 descend (@path)

like "lookup" except that it returns every object in the path, not just the leaf. the whole friend group, not just the one at the end πŸ«‚

🌸 "transform (\@path, $method, @args)"

performs a lookup on @path, applies the method $method with @args to the located node, and clones the path to the parent returning a derived tree.

this method is also implemented in Forest::Tree by mutating the tree in place and returning the original tree, so the same transformations should work on both pure trees and mutable ones. slay, compatibility πŸ’…

this code:

  my $new = $root->transform([ 1, 3 ], insert_child_at => 3, $new_child);

will locate the child at the path "[ 1, 3 ]", call "insert_child_at" on it, creating a new version of "[ 1, 3 ]", and then return a cloned version of "[ 1 ]" and the root node recursively, such that $new appears to be a mutated $root.

ngl that's a glow-up of the entire tree ✨

🌸 set_node $new

returns a clone of the tree node with the node value changed.

🌸 "replace $arg"

returns the argument. this is useful when used with "transform". little utility queen πŸ‘‘

🌸 clone

provided by MooseX::Clone.

deeply clones the entire tree. every last bit, fr fr 🧬

subclasses should use MooseX::Clone traits to specify the correct cloning behavior for additional attributes if cloning is used.

🌸 reconstruct_with_class $class

recursively recreates the tree by passing constructor arguments to $class.

does not use "clone". she's doing it from scratch, DIY icon πŸ”¨

🌸 to_mutable_tree

invokes "reconstruct_with_class" with Forest::Tree as the argument.

🌸 to_pure_tree

returns the invocant. she's already pure, she doesn't need to change for anyone πŸ’œ

🌸 get_child_index ($child)

returns the index of $child in "children" or undef if it isn't a child of the current tree. not your kid? undef. simple as 😌


✨ BUGS ✨

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. please be nice about it, the bug is just going through something πŸ™ˆ


✨ AUTHOR ✨

Yuval Kogman πŸ‘‘


Copyright 2008-2014 Infinity Interactive, Inc.

<http://www.iinteractive.com>

this library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. πŸŽ€


and that's the whole page bestie!! πŸ’– this one's perl v5.34.0, dated 2022-06-14, from the Forest...::Pure(3pm) manual β€” go forth and build immaculate little trees, ily, bye!! πŸŒΈπŸ¦‹βœ¨

πŸ“¦ where this page comes from