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

Heylo all, did some searching and couldn't find the answer I was hoping for, so just checking to see if there is a way to do what I want. I have input data stored in a Hash that was parsed from an XML structure, the keys are the element tag of the structure, so what would I like to do is call a function based on the key value. For example, if I have the following
%sample = ( location => .somedata.);
And I have a subroutine called location, I would like to determine if the key is a valid sub (may not as it is input data) and if it is call it.
foreach $key (keys %sample) { &$key($sample{$key}) if ($key <is a valid name of a subroutine>); }
I could hard code the keys into some type of Switch code that calls the proper subroutine, but that means I need change that every time I add a new handler (subroutine). I was hoping to just add new subroutines without changing the core flow of the application.

Replies are listed 'Best First'.
Re: Subroutines reference from data
by chip (Curate) on Mar 22, 2004 at 23:02 UTC
    For most purposes, the UNIVERSAL::can method will serve:

    if (my $code = main->can($key)) { &$code() };

    If you don't mind turning off strict 'refs', there's the ever-popular defined:

    &$key() if defined &$key;

    edited: to make the first example strict-safe. Thanks, tinita.

        -- Chip Salzenberg, Free-Floating Agent of Chaos

      &$key() if main->can($key);
      is not strict safe, but:
      if (my $sub = main->can($key)) { $sub->(); }
      also nice (but maybe too obfuscated?) would be (main->can($key)||sub{})->();
      First, Thanks for the quick reply. Gotta love it! Second, Worked excellent. Thanks.
Re: Subroutines reference from data
by waswas-fng (Curate) on Mar 22, 2004 at 23:20 UTC
    What you are looking for is a dispatch table it is covered here on many many posts, take a look aroud super search for some examples.


    -Waswas