I'm trying to build a large application with the main functionality abstracted out to subroutines. There are two ways of doing an important job, and four different structures against which the job may be run — meaning that there are eight possible job/structure combinations from which the program must choose, based on configuration settings gathered earlier. Also, each of the eight combinations needs to accept many arguments.

Each of the eight combination subroutines accepts a bunch of arguments, structures internal data, performs initial setup actions, and then returns an iterator in the form of an anonymous sub (a big shout-out and thank you to MJD!).

The problem lies in choosing the correct subroutine. I can get each of the subroutines to work by calling it directly from my main code, but every way I've tried to interject the selection process — including dispatch tables, switch statements, etc. — results in the anonymous subroutine (i.e. iterator) not being returned and a "strict refs" error based on calling a sub with an empty string as the only identifier; with "strict refs" turned off, it gives an undefined subroutine error.

This works:
sub increment { my ( $number, $incval ) = @_; return sub { $number += $incval; return $number; } } my $action = increment( 1, 2, 'plus', 'tons', 'more', 'arguments' ); while ( my $result = $action->() ) { print "$result\n"; }
Before you complain, yes, I know that this will print an infinite list of odd numbers; please rest assured that my actual application returns an exhaustible iterator.

This (and many other permutations of it I've tried) does not work, produces error "Can't use string ("") as a subroutine ref while "strict refs" in use at....":
sub do_something { my $action = shift( @_ ); for ( $action ) { when ( /INCREMENT/ ) { \&increment( @_ ) } default { die "You idiot!" } } } sub increment { my ( $number, $incval ) = @_; return sub { $number += $incval; return $number; } } my $action = do_something( 'INCREMENT', 1, 2, 'long', 'list' ); while ( my $result = $action->() ) { # <-- The error happens here print "$result\n"; }
How can I select the correct job/structure subroutine, send all necessary arguments, and get back a usable iterator?

This is my most desperate hour. Help me, Perl Monks. You're my only hope.

In reply to Choosing between multiple closures by oakb

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.