Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Automatically add all defined functions to your @EXPORT

by merlyn (Sage)
on Jun 21, 2005 at 11:55 UTC ( [id://468641]=CUFP: print w/replies, xml ) Need Help??

This snippet updates @EXPORT so that all of your defined functions in the current package are exported.

Do not execute this in a BEGIN block, or it'll be too early. You want to let the compiler first read the whole file first, then execute this code on the run pass.

Consider also using @EXPORT_OK instead of @EXPORT, so that your list of exported functions doesn't accidentally change.

Also, you can add more restrictions to the grep to exclude functions that begin with an underscore, for example.

our @EXPORT = do { no strict 'refs'; grep exists &$_, keys %{ __PACKAGE__ . '::'}; };

upate: changed "defined" to "exists" after much discussion.

Replies are listed 'Best First'.
Re: Automatically add all defined functions to your @EXPORT
by ysth (Canon) on Jun 21, 2005 at 18:58 UTC
    To pick up declared but not defined subs, use exists &$_ instead. Also, avoid all-uppercase names.* Example:
    package Foo; use strict; use warnings; our @EXPORT = do { no strict 'refs'; grep exists &$_ && /[a-z]/, keys %{ __PACKAGE__ . '::'}; }; sub bar; sub AUTOLOAD { our $AUTOLOAD; print "AUTOLOADing $AUTOLOAD\n"; } 1;
    *perlsub says:
    Subroutines whose names are in all upper case are reserved to the Perl core, as are modules whose names are in all lower case. A subroutine in all capitals is a loosely-held convention meaning it will be called indirectly by the run-time system itself, usually due to a triggered event. Subroutines that do special, pre-defined things include AUTOLOAD, CLONE, DESTROY plus all functions mentioned in perltie and PerlIO::via.

    Update: changed [_a-z] to [a-z], based on the new CLONE_SKIP method; but perhaps that ought to be CLONESKIP...

Re: Automatically add all defined functions to your @EXPORT
by dragonchild (Archbishop) on Jun 21, 2005 at 13:58 UTC
    As an example of what merlyn is talking about, you can do something like:
    our @EXPORT = do { no strict 'refs'; grep { !/^_/ } grep { defined &$_ } keys %{ __PACKAGE__ . '::'}; };

    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?
      our @EXPORT = do { no strict 'refs'; grep { !/^_/ } grep { defined &$_ } keys %{ __PACKAGE__ . '::'}; };
      Well, I was envisioning something more along the lines of:
      our @EXPORT = do { no strict 'refs'; grep { defined &$_ and not /^_/; } keys %{ __PACKAGE__ . '::'}; };
      I mean, you already have a grep there. Use it. {grin}

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        This is an interesting style difference. I prefer putting one very specific item per map or grep. I find it makes both comprehension and maintenance easier in the long run. Maybe, this is a meditation in the making?

        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?

      I'm not sure where I'm missing something, but why the "do"? It makes this not work for me; I must be missing something somewhere.

      for(split(" ","tsuJ rehtonA lreP rekcaH")){print reverse . " "}print "\b.\n";
        The do is to introduce a new scope during an assignemnt. "not work for me" is rather vague - you want to elaborate, possibly with the actual error message?

        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?
Re: Automatically add all defined functions to your @EXPORT
by tlm (Prior) on Jun 21, 2005 at 15:26 UTC

    Not only very handy, but IMO, a textbook example of the Snippet genre.

    I will make a tiny modification for my use:

    grep +( defined &$_ and !/^_/ ), keys %{ __PACKAGE__ . '::'};
    ...to keep _private_functions and __ANON__...s unexported.

    Update: I just realized that what I wrote above is almost identical to merlyn's earlier earlier follow-up... D'oh!

    the lowliest monk

      __ANON__
      I realize you struck that out, but I just tested, and even though creating an anonymous subroutine pokes an __ANON__ into the symbol table, the defined test fails, so this would never pick up on that. Unless you happened to also call a subroutine __ANON__.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        Well, I'm glad you checked, because I had a (rather embarrassing) bug in my test, which incorrectly showed the __ANON__s as passing the defined &$_ .

        the lowliest monk

Re: Automatically add all defined functions to your @EXPORT
by dragonchild (Archbishop) on Sep 21, 2005 at 02:03 UTC
    Note - if you're wanting to generalize this to any package name, you would do something like :
    my @function_names = grep { !/^_/ && /^[a-z_]+$/ } grep { exists &{${ $CLASS . '::'}{$_}} } keys %{ $CLASS . '::'};

    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?

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2024-04-20 08:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found