File Coverage

blib/lib/WE/Util/GenericTree/FromString.pm
Criterion Covered Total %
statement 40 43 93.0
branch 7 10 70.0
condition 1 3 33.3
subroutine 6 6 100.0
pod 1 2 50.0
total 55 64 85.9


line stmt bran cond sub pod time code
1             # -*- perl -*-
2              
3             #
4             # $Id: FromString.pm,v 1.4 2007/10/03 10:24:50 eserte Exp $
5             # Author: Slaven Rezic
6             #
7             # Copyright (C) 2001 Onlineoffice. All rights reserved.
8             # Copyright (c) 2002 Slaven Rezic. All rights reserved.
9             # This is free software; you can redistribute it and/or modify it under the
10             # terms of the GNU General Public License, see the file COPYING.
11             #
12             # Mail: slaven@rezic.de
13             # WWW: http://we-framework.sourceforge.net
14             #
15              
16             package WE::Util::GenericTree::FromString;
17              
18             =head1 NAME
19              
20             GenericTree::FromString - creating GenericTrees from a string representation
21              
22             =head1 SYNOPSIS
23              
24             my $tree = new GenericTree::FromString <
25             A
26             AA
27             AB
28             AC
29             ACA
30             ACB
31             AD
32             AE
33             B
34             C
35             CA
36             EOF
37             $tree->isa("GenericTree"); # yes
38              
39             =head1 DESCRIPTION
40              
41             =cut
42              
43 2     2   11 use strict;
  2         4  
  2         79  
44 2     2   11 use vars qw($VERSION @ISA);
  2         3  
  2         193  
45             $VERSION = sprintf("%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/);
46             # use base does not work for 5.005?
47 2     2   1351 use WE::Util::GenericTree;
  2         5  
  2         254  
48             push @ISA, 'WE::Util::GenericTree';
49              
50             # from: http://groups.google.com/group/perl.perl5.porters/browse_frm/thread/6f5edc58ec8ee045
51             sub rebless ($$){
52 12     12 0 23 my ($self, $newclass) = @_;
53 12 50       28 if ($] < 5.009) {
54 0         0 bless $self, $newclass;
55 0         0 return $self;
56             }
57 12         23 my $oldclass = ref $self;
58 12         122 require Hash::Util; # caveat; prototype does not work because of this
59 12         54 &Hash::Util::unlock_hash(\%$self);
60 12         362 bless $self, $newclass;
61 2     2   19 no strict 'refs';
  2         5  
  2         703  
62 12         27 &Hash::Util::lock_keys(\%$self, keys %{$oldclass.'::FIELDS'});
  12         69  
63 12         710 return $self;
64             }
65              
66             sub new {
67 12     12 1 42 my $proto = shift;
68 12         23 my $string_rep = shift;
69 12   33     103 my $class = ref($proto) || $proto;
70              
71 12         94 my $root = my $tree = new WE::Util::GenericTree {Id => ""}; # root
72 12         22 my $last_level = -1;
73 12         60 foreach my $line (split /\n/, $string_rep) {
74 80         271 $line =~ /^(\s*)(.*)/;
75 80 50       308 my $level = defined $1 ? length $1 : 0;
76 80         167 my $value = $2;
77 80 50       308 if ($level > $last_level+1) {
    100          
    100          
78 0         0 die "Too big jump from level $last_level to level $level in line $line";
79             } elsif ($level == $last_level+1) {
80 50         132 my $subtree = $tree->subtree($value);
81 50         58 $last_level++;
82 50         107 $tree = $subtree;
83             } elsif ($level == $last_level) {
84 10         33 $tree = $tree->parent->subtree($value);
85             } else {
86             #warn "$level .. $last_level $value";
87 20         50 for ($level .. $last_level-1) {
88 25         72 $tree = $tree->parent;
89 25         48 $last_level--;
90             }
91 20         51 $tree = $tree->parent->subtree($value);
92             }
93             }
94              
95 12         48 rebless $root, $class;
96             }
97              
98             1;
99              
100             __END__