Monks ~

Perl, sadly, is doing what I tell it to, rather than what I want. I'm using a nested hash as a configuration structure; in the code below is a bare-bones example. Most actions within a page use the same config_item (names changed to protect the innocent), but every now and then an action (e.g. the devious "action3" below) needs a different config_item. So I thought I'd add another nesting level and figure out a way to detect those special cases (they happen often enough, and are useful enough, that I'd hate to factor them out). Other than simplification, the only substantive change from my working code is that my subrefs are named rather than anonymous.
my %runmodes = ( config_item => 'regular', action1 => sub{ print "action = 1" }, action2 => sub{ print "action = 2" }, action3 => { config_item => 'special', subroutine => sub{ print "action = 3" }, }, ); sub get_config_item { my( $runmodes, $action ) = @_; my $config_item = $runmodes->{ config_item }; if( exists $runmodes->{ $action }{ subroutine } ) { # error line &{ $runmodes->{ $action }{ subroutine }}; $config_item = $runmodes->{ $action }{ config_item }; } else { &{ $runmodes->{ $action }} } return $config_item; } print ", ", get_config_item( \%runmodes, "action3" ), "\n"; print ", ", get_config_item( \%runmodes, "action1" ), "\n"; # OUTPUT # # action = 3, special # Not a HASH reference at str.pl line 22.
The "exists" test on the error line isn't the first thing I tried, just the most recent, and it's nicely illustrative of what I want to do. I understand why the error's happening, but I can't think of a way to check for that subref without dying (eval, perhaps, but I'm hoping there's another way). I also know I could standardize the hash structure as follows (with attendent changes in the rest of the code, of course):
my %runmodes = ( config_item => 'regular', action1 => { subroutine => sub{ print "action = 1" }}, action2 => { subroutine => sub{ print "action = 2" }}, action3 => { config_item => 'special', subroutine => sub{ print "action = 3" }}, }, );
But two things bug me about that solution. First, those extra "subroutine"s sitting there, redundant, look ugly. Second, regardless of how I solve this particular problem, I still don't know if there's a way to do what I'm trying. Thanks muchly for any assistance.
--
man with no legs, inc.

In reply to Testing for existence of subroutine ref? by legLess

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.