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

I have a whole set of functions called:
sub mod_ram_usage();
sub mod_disk_usage();
sub mod_etc...

and I would like to call each in turn:
foreach $function (LIST_OF_FUNCTIONS) {
if ($function ~= /^mod_/) {
&$function();
}
}

How do I get the list of all functions in context right now ?

Thanks.
Pat
patrickn@tygerteam.com

Replies are listed 'Best First'.
Re: Looping on function names
by btrott (Parson) on Jul 19, 2000 at 23:05 UTC
    You could look them up in the symbol table, but I'd recommend another approach. Store the list of functions in a hash as a list of subroutine references. Like this:
    my %functions = ( 'ram_usage' => \&mod_ram_usage, 'disk_usage' => \&mod_disk_usage, ... ); for my $name (keys %functions) { $functions{$name}->(); }
(chromatic) Re: Looping on function names
by chromatic (Archbishop) on Jul 19, 2000 at 23:09 UTC
    You can hop through the symbol table at runtime. The following code is a bit ugly, but it works with my testing:
    #!/usr/bin/perl -w use strict; my $name = "chromatic"; my $quest = "nefarious symbol wrangling"; sub findme { # just has to be defined return 0; } foreach (keys %main::) { # use whichever package you prefer no strict 'refs'; # else the next line fails if (defined *{$_}{CODE}) { print "$_\n"; # could be pushed onto an array, into a h +ash } }
    The trick is knowing that you can access a symbol table with %main:: or %packagename:: or %:: for the current package.

    The typeglob trickery in the defined line just looks to see if there's a CODE bit in the current package.

    Personally, I'd just keep a hash of subroutine names and references around:

    my %subs = ( mod_disk => \&mod_disk, mod_ram => \&mod_ram, mod_sticky_note => \&mod_sticky_note, mod_gum_wrapper => \&mod_gum_wrapper );
      i just wanted to say, that this:
      foreach (keys %main::) { # use whichever package you prefer no strict 'refs'; # else the next line fails if (defined *{$_}{CODE}) { print "$_\n"; # could be pushed onto an array, } # into a hash }
      both terrifies me, and amazes me. i guess, i know you can do that, and i'm pretty sure i've done it myself... but damn... next time anyone tells me perl isn't a real language that alows you to do powerful things, i'm going to shove this example of raw power down their throats.
Re: Looping on function names
by lhoward (Vicar) on Jul 19, 2000 at 23:24 UTC
    The unclean way to do that that I do not reccomend is with symbolic references. It is so discouraged I will not even go into how to do it.

    The proper way would be to build a list/hash of function references and iterate through it.

    my @f=(\&mod_ram_usage,\&mod_disk_usage); foreach(@f){ &$_; }