Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, I have a perl module which has specifically formatted functions:
$ACodes = {...}; #hash table ref sub getAStruct { return $ACodes; } $BCodes = {...}; #hash table ref sub getBStruct { return $BCodes; } ...
There could be any number of these constructs, and they could have any name (A & B are just examples) but they all conform to the same format: get + <name> + Struct. Can anyone suggest a way I could somehow loop through these functions so I could access the hash tables. Thanks, Michael

Replies are listed 'Best First'.
Re: Grabbing unknown functions from modules
by Abigail-II (Bishop) on Sep 29, 2003 at 15:29 UTC
    #!/usr/bin/perl use strict; use warnings; package Foo; sub getAStruct { print "This is getAStruct\n"; } sub getBStruct { print "This is getBStruct\n"; } sub getCStruct { print "This is getCStruct\n"; } package main; foreach my $key (keys %Foo::) { no strict 'refs'; "Foo::$key" -> () if defined &{"Foo::$key"}; # Or: # "Foo::$key" -> () if defined *{"Foo::$key"}{CODE}; } __END__ This is getAStruct This is getCStruct This is getBStruct

    Abigail

      Thanks so much Abigail, it worked beautifully ;)
Re: Grabbing unknown functions from modules
by dragonchild (Archbishop) on Sep 29, 2003 at 15:40 UTC
    Personally, this sounds like a bad design to me. I would've built a function called getStruct() and pass it in A or B (or whatever). That function would then act as a dispatch table.

    Or, if you really want to get the names (to loop through or whatever), I'd do the following:

    package Struct::Stuff; use Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( %Struct_Dispatch ); my %Struct_Dispatch = ( A => \&__PACKAGE__::getAStruct, B => \&__PACKAGE__::getBStruct, # And so on ... ); sub getAStruct { } sub getBStruct { } ------- # In your main program ... use Struct::Stuff qw(%Struct_Dispatch); # Later ... foreach my $type (keys %Struct_Dispatch) { print "Doing '$type'\n"; my $val = $Struct_Dispatch{$type}->(); print "\tReturns '$val'\n"; }

    If you build it right, there's no reason to loop through the symbol table or use some of the development modules. That stuff is black magic and most people don't know how to use them.

    ------
    We are the carpenters and bricklayers of the Information Age.

    The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: Grabbing unknown functions from modules
by broquaint (Abbot) on Sep 29, 2003 at 15:28 UTC
    If those hashes live in the symbol table of the package then it could be a simple matter of applying Devel::Symdump e.g
    use Devel::Symdump; require Your::Module; my @hashes = grep { ref $_ eq 'HASH' } Devel::Symdump->scalars("Your::Module");
    Failing that, you could just use call the subroutines that match your specification
    my @hashes = map &$_, grep /::get(\w+)Struct$/, Devel::Symdump->functions("Your::Module");
    Note that neither of the above examples use strict because of the use of symbolic references.

    HTH

    _________
    broquaint