File Coverage

blib/lib/Text/Spintax/RenderNode.pm
Criterion Covered Total %
statement 18 36 50.0
branch 7 16 43.7
condition n/a
subroutine 2 4 50.0
pod 2 3 66.6
total 29 59 49.1


line stmt bran cond sub pod time code
1             package Text::Spintax::RenderNode;
2              
3 2     2   10 use Text::Spintax::Mo;
  2         3  
  2         12  
4              
5             has 'parent' => (
6             is => 'rw',
7             );
8              
9             has 'children' => (
10             is => 'rw',
11             );
12              
13             has 'weight' => (
14             is => 'rw',
15             );
16              
17             has 'text' => (
18             is => 'rw',
19             );
20              
21             has 'type' => (
22             is => 'rw',
23             );
24              
25             =head1 SUBROUTINES/METHODS
26              
27             =head2 render
28              
29             Generates a text string from all the possible variations. Uses weights to determine how likely each possible string is to be rendered.
30              
31             =cut
32              
33             sub render {
34 505     505 1 1116 my $self = shift;
35 505 100       903 if ($self->type eq "text") {
    100          
    50          
36 303         596 return $self->text;
37             }
38             elsif ($self->type eq "spin") {
39 101         107 my $total = 0;
40 101         90 foreach my $child (@{$self->children}) {
  101         188  
41 202         448 $total += $child->weight;
42             }
43 101         209 my $rand = rand $total;
44 101         94 foreach my $child (@{$self->children}) {
  101         210  
45 143         286 $rand -= $child->weight;
46 143 100       392 $rand <= 0 and return $child->render;
47             }
48             }
49             elsif ($self->type eq "sequence") {
50 101         97 return join "", map { $_->render } @{$self->children};
  303         463  
  101         186  
51             }
52             else {
53 0           die "invalid type";
54             }
55             }
56              
57             sub equal_path_weight {
58 0     0 0   my $self = shift;
59 0           $self->weight($self->num_paths);
60 0 0         foreach my $child ($self->children ? @{$self->children} : ()) {
  0            
61 0           $child->equal_path_weight;
62             }
63             }
64              
65             =head2 num_paths
66              
67             Returns the number of possible strings that could be generated from this node. Combinatorially speaking, children of a sequence node multiply and children of a spin node add.
68              
69             "{a|b|c}" has 1+1+1=3 possibilities: a, b, c
70              
71             "{a|b} {c|d}" has 2*2=4 possibilities: a c, a d, b c, b d
72              
73             =cut
74              
75             sub num_paths {
76 0     0 1   my $self = shift;
77 0 0         if ($self->type eq "spin") {
78 0           my $num_paths = 0;
79 0 0         foreach my $child ($self->children ? @{$self->children} : ()) {
  0            
80 0           $num_paths += $child->num_paths;
81             }
82 0           return $num_paths;
83             }
84             else {
85 0           my $num_paths = 1;
86 0 0         foreach my $child ($self->children ? @{$self->children} : ()) {
  0            
87 0           $num_paths *= $child->num_paths;
88             }
89 0           return $num_paths;
90             }
91             }
92              
93             1;