Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Local Subroutines

by sweetblood (Prior)
on May 27, 2004 at 18:37 UTC ( [id://357005]=perlquestion: print w/replies, xml ) Need Help??

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

Is it possible to create a subroutine inside another sub that is local only to the sub it is in?
I have several subs that are called based on protocol. I'd like each of them to have there own set of subroutines.

Is this just bad form, should I just use uniquley named global subs?

Thanks!

Sweetblood

Replies are listed 'Best First'.
Re: Local Subroutines
by l3nz (Friar) on May 27, 2004 at 18:49 UTC
    Not sure if that's what you're looking for, but you may have a look at anonymous functions - they're quite powerful and deserve a good bit of attention for themselves. :-)

    I'd have a look at broquaint's excellent Closure on closures where anonymous functions and funny things you can do with them are thoroughly explained.

      I guess this is a good time to buckle down and study.
      Thanks for the excellent reference.++

      Sweetblood

Re: Local Subroutines
by Fletch (Bishop) on May 27, 2004 at 18:49 UTC

    A better step would be to place refs to the correct subs in different packages in a hash and use those as a dispatch table. Of course if you do that you'd probably be better off going the OOP route and make classes and use inheritence (or something like the State or Strategy pattern) to vary behavior.

    my $dispatch = { foo => { bar => \&foo::bar, baz => \&foo::baz }, quux => { bar => \&quux::bar, baz => \&quux::baz } }; $dispatch->{ $type }->{ $operation }->( @args );
Re: Local Subroutines
by Zaxo (Archbishop) on May 27, 2004 at 19:05 UTC

    A code reference can be assigned to a local or lexical (my) variable. Named subs are always package global.

    Here is a sub which takes a list of code references and returns a coderef to a function which executes them in order on @_.

    # Usage: my $code = codestick( \&foo, \&bar, \&baz); # Call with $code->(LIST); sub codestick { my @subs = @_; sub { &$_ for @subs; } }
    That's not necessarily a design you'd want, but it illustrates the syntax. The weaknesses include implied strong coupling between subs you'd list in the codestick call through their need to cooperate over @_.

    After Compline,
    Zaxo

Re: Local Subroutines
by dragonchild (Archbishop) on May 27, 2004 at 19:05 UTC
    It sounds like you're really looking for objects, not subroutines.

    That said, you can do something like:

    sub foo { my ($start, $num) = @_; my $_foo; *_foo = sub { # Do stuff here }; my @return = $_foo->($start, $num); return @return; }

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

    I shouldn't have to say this, but any code, unless otherwise stated, is untested

      Aren't you globbing a lexical here?

      The PerlMonk tr/// Advocate
        Lexicals can't be globbed (whatever that means ;) because they're lexical, not global (they don't live in the symbol table):
        my $foo = sub {'i am $foo '}; *foo = sub{'i am *foo '}; print $foo->(), $foo,$/; print foo(), \&foo,$/; __END__ i am $foo CODE(0x1ab2860) i am *foo CODE(0x1ab28e4)

        MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
        I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
        ** The third rule of perl club is a statement of fact: pod is sexy.

      I've always managed to skirt around objects, using them only when I have to, but never creating my own. I've been programming over 20 years(not always Perl), so objects were never part of my vernacular except of course as in my roll as a sex object(maybe not). I suppose this is a good time to finally bite the bullet.

      Thanks!
      Sweetblood

Re: Local Subroutines
by educated_foo (Vicar) on May 28, 2004 at 07:07 UTC
    It's fine form --
    sub bar { print "global bar(@_)\n"; } sub foo { local *bar = sub { print "bar(@_)\n"; }; bar(1..3); } foo; bar;
    But remember that these are dynamically-scoped.
    update: missing semicolon.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://357005]
Approved by l3nz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2024-04-25 05:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found