vinoth.ree has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I was doing somthing wrong, pls help me on this.

I was trying to print the symble table of a package of mine.below is my package code

package Vinoth; use strict; use warnings; use Data::Dumper; our $VERSION=1.0; sub printSimbleTable{ my $package = shift; print "I am in printSimbleTable of : $package\n"; print Dumper \%$packge::; #Not working print Dumper \%Vinoth::; # Works #print Dumper \%{$packge}::; #Not working # foreach my $varName (sort keys %$package::) # { # print "$varName\n"; # local *typeglob = %{$package}::{$varName}; # print "$$varName\n" if ($typeglob); # } } 1;

I tried to use this package in a perl script and calling a function in this module to print the package's symble table. Below is the script file

use strict; use warnings; use Vinoth; &Vinoth::printSimbleTable( 'Vinoth' );

As you can see this line print Dumper \%$packge::; #Not working the $package hash my module name 'Vinoth', but its not printing the symble table with the Dumper, when I replace it with the my module name explicity, it works. how to use $package variable here and make it work ?

Reference:

Packages and Symbol Tables

A package's namespace is a symbol table. The name of your package is stored in a hash named after your package with two colons appended to it. If you name a package BushWhack, its symbol table name is %BushWhack::. Packages are represented as %main:: or %:: in the symbol table by default. Since we're dealing with a hash, each key must have a value. Because keys are identifiers, values are the corresponding typeglob values; globs are pretty efficient because they do the symbol table lookups at compile-time. In other words, *BushWhack represents the value of %BushWhack::--see the following:

local *low_flyer = *BushWhack::variable; # compile time local *low_flyer = *BushWhack::{"variable"}; # run time

You can look up all the keys and variables of a package with this example. You may use undef() on these to clear their memory, and they will be reported as undefined. You shouldn't undefine anything here unless you don't plan to load these packages again. Because the memory has already been filled, it saves time when you load them if you leave them defined:1

foreach $symbol_name (sort keys %BushWhack::) { local *local_sym = $BushWhack::{$symbol_name}; print "\$$symbol_name is defined\n" if($local_sym); print "\@$symbol_name is defined\n" if(@local_sym); print "\%$symbol_name is defined\n" if(%sym); }


All is well

Replies are listed 'Best First'.
Re: print package's symble table
by Discipulus (Canon) on Jul 22, 2014 at 08:51 UTC
    uhuuh black magic.. i like it (i used with not full understanding here, check some useful links).

    Why pass the package name? you have already at your disposal (on > 5.16 you have __SUB__ too, view perldata):
    sub printSimbleTable{ #my $package = shift; print "I am in printSimbleTable of: ".__PACKAGE__."\n"; no strict qw (refs); print map {"$_\n"} keys %{__PACKAGE__."::"} }

    HtH
    L*
    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: print package's symble table
by ikegami (Patriarch) on Jul 22, 2014 at 17:49 UTC

    Using a reference:

    $ perl -MData::Dumper -e' sub Foo::Bar::baz {} print(Dumper(\%Foo::Bar::)) ' $VAR1 = { 'baz' => *Foo::Bar::baz };

    Using a symbolic reference:

    $ perl -MData::Dumper -e' sub Foo::Bar::baz {} print(Dumper(\%{"Foo::Bar::"})); ' $VAR1 = { 'baz' => *Foo::Bar::baz };

    Neither hardcoded nor a symbolic reference:

    $ perl -MData::Dumper -e' sub Foo::Bar::baz {} print(Dumper(\%{ $::{"Foo::"}{"Bar::"} })); ' $VAR1 = { 'baz' => *Foo::Bar::baz };

    So, you can do

    no strict 'refs'; \%{ $package . '::' };

    or you can do

    my $r = \%::; $r = $r->{$_ . '::'} for split /::/, $package; \%$r
Re: print package's symbol table
by LanX (Saint) on Jul 22, 2014 at 09:40 UTC
    > module name 'Vinoth', but its not printing

    Its very simble ... Package:: names always end with two colons.

    And strict could cause a problem but you didn't show us the error-msgs... ("doesn't work" doesn't help!)

    Hint  no strict q/refs/ at start of subroutine might help.

    Cheers Rolf

    (addicted to the Perl Programming Language and ☆☆☆☆ :)

Re: print package's symble table
by Arunbear (Prior) on Jul 22, 2014 at 10:40 UTC
    Try playing around in the debugger e.g. :
    +11:32% perl -de0 Loading DB routines from perl5db.pl version 1.32 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(-e:1): 0 DB<1> $Foo::bar = 1 DB<2> *Foo::fun = sub { 42 } DB<3> p $Foo::bar 1 DB<4> p Foo::fun() 42 DB<5> x \ %Foo:: 0 HASH(0x2757b98) 'bar' => *Foo::bar 'fun' => *Foo::fun DB<6> $p = 'Foo' DB<7> x \ %{"${p}::"} 0 HASH(0x2757b98) 'bar' => *Foo::bar 'fun' => *Foo::fun DB<8> q +11:33%