in reply to Composing or chaining subroutines

Is eval to evil for this? ;)

use strict; use warnings; my $chain1 = chain(qw( rev Foo::uc b2_ )); my $chain2 = chain(qw( Foo::uc b2_ rev )); print for $chain1->(qw( foo bar baz )); print for $chain2->(qw( foo bar baz )); sub chain { my $str = '@_'; $str = '&' . "$_($str)" for @_; return sub { eval $str }; } sub rev { map scalar reverse, @_ } sub b2_ { my @a=@_;map {s/b/_/g;$_} @a } package Foo; sub uc { map ucfirst, @_ }

jeffa

L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
B--B--B--B--B--B--B--B--
H---H---H---H---H---H---
(the triplet paradiddle with high-hat)

Replies are listed 'Best First'.
Re^2: Composing or chaining subroutines
by dragonchild (Archbishop) on Jan 17, 2006 at 17:14 UTC
    I should have mentioned it in the main post, but I wanted to avoid eval for several reasons:
    1. There is a pretty hefty performance penalty when doing string eval
    2. What do I do with syntax errors? If I'm stitching subrefs, I know they compile.
    3. How do I stitch closures together?

    The impetus for this was this syntax:

    class Foo => { class_method 'c_foo' => signature (Int, Num(5)), body => { ... }; method 'foo' => signature (Any, Hash), returns ( Int ), body => { ... }; }; Foo->add_post_process( methods => 1, class_methods => 0, action => sub { ... }, );
    The idea being that you first have a check for if the referent is a class name or a blessed reference into that class. Then, you have a check on the parameters being passed in. All of these are really easily done as closures. Except, now every single method call has some 10-40 subroutines that stack 2-3 above the body of the method which, itself, is stacked. That's a massive performance penalty, plus it makes debugging errors extremely difficult.

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?