use 5.032001; use warnings; #use Data::Dumper; use PPI; use PPR::X; #use PPI::Dumper; use Scalar::Util qw(blessed); my $PTR; my @PACKAGE=('main','main'); # Just a useful routine during delousing sub as_header { my $string=(' > ' x $PTR).ref shift; return $string.('='x (64-length $string)); }; sub process_chunk { $PACKAGE[++$PTR]=undef; for my $node (shift->children) { next # This should never happen! unless (blessed $node); next # WE don't care about these do we?? if ($node->isa('PPI::Statement::Null') || $node->isa('PPI::Token::Comment') || $node->isa('PPI::Token::Whitespace') || $node->isa('PPI::Token::Structure')); #say as_header($node); if ($node->isa('PPI::Structure::Block')) { #say $node->content; } elsif ($node->isa('PPI::Statement::Package')) { #say $node->content; #say $node->child(2)->content; $PACKAGE[$PTR]=$node->child(2)->content; } elsif ($node->isa('PPI::Statement::Sub')) { #say $node->content; my $name=$node->child(2)->content; unless ($name =~ m{::}) { for (my $i=$PTR; $i >= 0; $i--) { if (defined $PACKAGE[$i]) { $name=qq{$PACKAGE[$i]::$name};#' last; }; }; }; say $name; } else { #PPI::Dumper->new($node,whitespace=>0)->print; }; # See if further processing is possible process_chunk($node) if (blessed $node && $node->can('children')); } $PTR--; }; # sub process_chunk: my $chunk=do { local $/; }; # Let's let Conway confirm all is good to go! unless ($chunk =~ m{ (?&PerlEntireDocument) $PPR::X::GRAMMAR }x) { die "Invalid Perl code: " . $PPR::X::ERROR->source . "\n" } else { # Now go process the bloody thing! process_chunk(PPI::Document->new(\$chunk)); }; __DATA__ sub zero { # main::zero say __PACKAGE__.q{::zero}; }; package Fee; sub one { # Fee::one say __PACKAGE__.q{::one}; }; package Fi; sub two { # Fi::two say __PACKAGE__.q{::two}; }; { package Fo; sub three { # Foo::Three say __PACKAGE__.q{::three}; }; }; # End of package Foo! {; say "This block introduces no new package" }; sub Fum::four { # Fum::four say __PACKAGE__.q{:four}; }; sub four { # Fi::four say __PACKAGE__.q{:four}; }; package I_smell_the_blood_of_an_Englishman { # Package with a block sub five { # I_smell_the_blood_of_an_Englishman::five say qq{Fee-fi-fo-fum,\nI smell the blood of an Englishman,\nBe he alive, or be he dead\nI'll grind his bones to make my bread.}; }; };