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

This is driving me BANANAS (short a trip as that may be.)

Take the following code sample:

submit_thingamabob($handle,$not_today,$thingie,"Foo!",234); submit_thingamabob($handle,$not_today,$thingie,"Frob!",23); submit_thingamabob($handle,$not_today,$thingie,"Forb!",54); submit_thingamabob($handle,$not_today,$thingie,"ooF!",11); submit_thingamabob($handle,$not_today,$thingie,"broF!",fakenum); submit_thingamabob($handle,$not_today,$thingie,"Frap!",458);

Now multiply that by about 20. So I've got dozens of calls with the same parameter list (at the value level) except for the final couple. What's the right way to simplify this? Pulling all of the final pairs into their own hashes just for the purpose of iterating across them seems silly (especially since I'd have to explicity specify them all anyway. Why add semantic complexity?)

My intuition (such as it is) intuits that I should be able to distill it down with an inner subroutine reference somehow.

I'm not really looking to eliminate the "nubmer of lines", since that's necessary complexity (no matter where the can is kicked.) But the repetition of the first three parameters is driving me batty.


Replies are listed 'Best First'.
Re: Simplifying repeated parameter lists
by roboticus (Chancellor) on Sep 19, 2012 at 19:50 UTC


    Take advantage of list flattening:

    { # new scope so we don't blow up another @t my @t = ($handle, $not_today, $thingie); submit_thingamabob(@t, "Foo!", 234); submit_thingamabob(@t, "Frob!",23); submit_thingamabob(@t, "Forb!",54); submit_thingamabob(@t, "ooF!",11); submit_thingamabob(@t, "broF!",fakenum); submit_thingamabob(@t, "Frap!",458); }


    When your only tool is a hammer, all problems look like your thumb.

      I'm... retarded. Thanks robo o/

        Go one step further:

        sub x { return submit_thingamabob( $handle, $not_today, $thingie, @_ }; } x( "Foo!", 234 ); x( "Frob!", 23 ); x( "Forb!", 54 ); x( "ooF!", 11 ); x( "broF!", fakenum ); x( "Frap!", 458 );

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        RIP Neil Armstrong

Re: Simplifying repeated parameter lists
by Perlbotics (Bishop) on Sep 19, 2012 at 20:05 UTC


    submit_thingamabob( $handle, $not_today, $thingie, $_->[0], $_->[1]) for ( [ "Foo!" , 234 ], [ "Frob!", 23 ], [ "Forb!", 54 ], [ "ooF!", 11 ], [ "broF!", fakenum ], [ "Frap!", 458 ] );

      As much as I liked the hippo/BrowserUk solution, I think this appeals to me the most.

      It wraps the fundamentally iterative nature of what I'm doing without adding the slightest bit of unnecessary complexity.

      or somewhat tidier:

      submit_thingamabob($handle, $not_today, $thingie, @$_) for [Foo => 234], [Frob => 23], [Forb => 54], [ooF => 11], [Frap = +> 458];
      True laziness is hard work
Re: Simplifying repeated parameter lists
by hippo (Chancellor) on Sep 19, 2012 at 19:59 UTC
    How about just:
    sub go { submit_thingamabob ($handle, $not_today, $thingie, @_); } go ("Foo!",234); go ("Frob!",23);
      This is the type of thing that was kicking around in my head, and you and BrowserUk posted it within seconds of each other. I just couldn't quite get my head to how to search for it.

        couldn't quite get my head to how to search for it

        Did you have any search ideas? I'm interested, because its one of those things, if you don't know the name, its kind of hard to find,

        Tutorials: Closure on Closures

Re: Simplifying repeated parameter lists
by roboticus (Chancellor) on Sep 19, 2012 at 20:02 UTC


    I just had another amusing thought: Use a closure to hold your subroutine call with some of the arguments in place. It's a little more complicated, but if you've got multiple functions and/or sets of common arguments, I think it's a win::

    $ cat closure_call.pl #!/usr/bin/perl use strict; use warnings; # # Stuff you already have in your program # my ($handle, $not_today, $thingie) = qw($handle $not_today $thingie); sub printargs { print "printargs(", join(", ", @_), ")\n"; } # Get a reference to a function with some of the args already in place my $simple = simplificate(\&printargs, $handle, $not_today, $thingie); my $simpl2 = simplificate(\&printargs, "tittle", "tattle"); + # Function to build a reference with some arguments already in place sub simplificate { my ($rFn, @args) = @_; return sub { &$rFn(@args, @_) }; } # Now call it as you need it + &$simple("Foo!", 234); &$simple("Frob!",23); &$simple("Forb!",54); &$simple("ooF!",11); &$simple("broF!", 'fakenum'); &$simple("Frap!",458); &$simpl2("Whackmatic"); &$simpl2("Cybernicus"); &$simpl2("Canem Infernae"); $ perl closure_call.pl printargs($handle, $not_today, $thingie, Foo!, 234) printargs($handle, $not_today, $thingie, Frob!, 23) printargs($handle, $not_today, $thingie, Forb!, 54) printargs($handle, $not_today, $thingie, ooF!, 11) printargs($handle, $not_today, $thingie, broF!, fakenum) printargs($handle, $not_today, $thingie, Frap!, 458) printargs(tittle, tattle, Whackmatic) printargs(tittle, tattle, Cybernicus) printargs(tittle, tattle, Canem Infernae)

    Update: Darn! BrowserUk beat me to the punch!

    Update: Forgot to update code for simpl2.


    When your only tool is a hammer, all problems look like your thumb.

      I'm not gonna lie, my reaction was a healthy combination of "Neat! wait...why?"

      I'm keeping that in the bag of tricks, 'cause I think if I go spend some time in the machine shop I'll get hit with a "THAT'S why!".


        Admittedly, it's probably more "neat-o!" than practical. (Though it's just useful enough for me to drop into my bag-o-tricks module for general use.) It probably only pulls its weight when you have multiple sets of default arguments and/or multiple different functions you want to decorate.

        There might be a few useful variations, too. For example, might want to make a bunch of default arguments at the *end* of your list (such as for adding formats to cells using Spreadsheet::WriteExcel.


        When your only tool is a hammer, all problems look like your thumb.

Re: Simplifying repeated parameter lists
by Anonymous Monk on Sep 19, 2012 at 20:15 UTC

    simple in-editor substitution

    s{\Qsubmit_thingamabob($handle,$not_today,}{[ }g; s{\Q);}{ ],}g;

    a prefix and perltidy and I get

    my @repeaters = ( $handle, $not_today, $thingie ); submit_thingamabob( @repeaters, @$_ ) for [ "Foo!", 234 ], [ "Frob!", 23 ], [ "Forb!", 54 ], [ "ooF!", 11 ], [ "broF!", fakenum ], [ "Frap!", 458 ], ;;;;;

    Is it more complexity?

    I'm not sure, but I do know I iterate before I curry

    my $curry = sub { submit_thingamabob($handle, $not_today, $thingie, @_ ); }; $curry->( "Foo!", 234 ); $curry->( "Frob!", 23 ); $curry->( "Forb!", 54 ); $curry->( "ooF!", 11 ); $curry->( "broF!", fakenum ); $curry->( "Frap!", 458 );