#!perl use strict; use warnings; use feature qw (say); $|=1; use Diagnostics; use Data::Dumper; use Data::Dump::Streamer; my $cpan = {'.'=>'CPAN'}; #_=>'',__=>'' my $skiprx = qr/^\.{1,2}|\+$/; #our @names; &grow_tree; sub grow_tree { while (){ chomp; my @fields = split /\s+/;#say "@fields"; my @names = split /::/, $fields[0];#say "names($#names): @names"; my $cur; my @ancestors = @names; pop @ancestors; eval '$cpan->{'. # start od cpan container (join '}{', @names).'} ='. # expand names and vivifies because there is assignment '{'. # hasref start '"."=>$names[-1],'. '".."=> \%{$cpan'.(defined $ancestors[0] ?'->{'.(join '}{', @ancestors ).'}':'').','.'},'. '"+"=> [$fields[1],$fields[2]],'. '}; '; # hashref end } Dump($cpan); } my $current = \%$cpan;&header($current); while(){ chomp; if (exists $$current{$_} and $_ !~ $skiprx) { $current = \%{$$current{$_}}; } elsif($_ eq '.'){ say for grep !$skiprx, keys %$current; } elsif($_ eq '..'){ ref $current->{'..'} eq 'HASH' ? say "ok father defined for $current->{'.'}" : say "WARN no father defined"; #$current = \%{$current->{__}}||\%$cpan; $current = ref $current->{'..'} eq 'HASH' ? \%{$current->{'..'}}: \%$cpan; } elsif($_ eq '+'){ print join ' ', $current->{'.'},@{$current->{'+'}},"\n" } #or abstract? elsif($_ eq '*'){ foreach my $k (keys %$current) {next if $k=~$skiprx;print "$k @{$current->{$k}{'+'}}\n"} } #or abstract? else{next} } continue{&header($current); #print "CURRENT: ",$$current{_},"\n"; } sub header { my $hr = shift; print "#" x 35,"\n"; print "# CURRENT: ",$$hr{'.'}," has ",(scalar@{[grep !$skiprx, keys %$hr]})," namespaces\n"; print "#" x 35,"\n"; } __DATA__ ABI 1.0 M/MA/MALAY/ABI-1.0.tar.gz A 0.5 I/ID/IDOPEREL/Abilities-0.5.tar.gz A::BB 0.5 I/ID/IDOPEREL/Abilities-0.5.tar.gz A::CC 0.2 I/ID/IDOPEREL/Abilities-0.2.tar.gz A::CC::DD 0.2 I/ID/fake/Abilities-0.2.tar.gz XX::ZZ::YY 0.1 I/jhsjkha #!perl use strict; use warnings; use feature qw (say); $|=1; use Diagnostics; use Data::Dumper; use Data::Dump::Streamer; my $cpan = {'_'=>'CPAN'}; #_=>'',__=>'' #our @names; &grow_tree; sub grow_tree { while (){ chomp; my @fields = split /\s+/;#say "@fields"; my @names = split /::/, $fields[0];#say "names($#names): @names"; my $cur; my @ancestors = @names; pop @ancestors; #print "for '",(join '::',@names),"' ancestor is ",( $ancestors[$#ancestors]?(join '::',@ancestors) : 'CPAN' ),"\n"; #print "\t\t-->\$cpan",(defined $ancestors[0] ?'{'.(join '}{', @ancestors ).'}':''),"\n"; eval '$cpan->{'.(join '}{', @names).'} = {_=>$names[-1],__=> \%{$cpan'.(defined $ancestors[0] ?'->{'.(join '}{', @ancestors ).'}':'').'}' .'}; '; #print "\n-------------\n-------------\n"; } Dump($cpan); } my $current = \%$cpan;&header($current); while(){ chomp; #say +( defined $$current{_} ? $$current{_} : 'CPAN')," has ",(scalar@{[grep !/^_{1,2}$/, keys %$current]})," namespaces\n"; #print '#' x 34,"\nCURRENT",(Dump $current),"\n",'#' x 34,"\n"; if (exists $$current{$_} and $_ !~ /^_{1,2}$/) { $current = \%{$$current{$_}}; &header($current); } elsif($_ eq '_'){ say for grep !/^_{1,2}$/, keys %$current; &header($current);} elsif($_ eq '__'){ ref $current->{__} eq 'HASH' ? say "ok father defined for $current->{_}" : say "WARN no father defined"; #$current = \%{$current->{__}}||\%$cpan; $current = ref $current->{__} eq 'HASH' ? \%{$current->{__}}: \%$cpan; &header($current); } else{next} } #continue{ #say +( defined $$current{_} ? $$current{_} : 'CPAN')," has ",(scalar@{[grep !/^_{1,2}$/, keys %$current]})," namespaces\n"; #print '#' x 34,"\nCURRENT",(Dump $current),"\n",'#' x 34,"\n"; #} sub header { my $hr = shift; #Dump $hr; print "CURRENT: ",$$hr{_},"\n"; #say +( defined $hr->{_} ? $hr->{_} : 'CPAN'), # " has ",(scalar@{[grep !/^_{1,2}$/, keys %$$hr]})," namespaces\n"; } __DATA__ ABI 1.0 M/MA/MALAY/ABI-1.0.tar.gz A 0.5 I/ID/IDOPEREL/Abilities-0.5.tar.gz A::BB 0.5 I/ID/IDOPEREL/Abilities-0.5.tar.gz A::CC 0.2 I/ID/IDOPEREL/Abilities-0.2.tar.gz A::CC::DD 0.2 I/ID/fake/Abilities-0.2.tar.gz XX::ZZ::YY 0.1 I/jhsjkha