I'm working on a non-OO module that has a number of subs that are dynamically created and added to the symbol table. Their names are known at compile time, so I could certainly hard-code them in, but I'm a fan of DRY and would rather just specify them once.

When the module is loaded I have several subs that are string-eval'd into existence. In reality the body of the subs is more complex than a simple tr//, but this demonstrates the problem well enough. Everything works fine, but I'm stuck on the simple task of convincing Exporter::Easy to export the subs. I can make it work with Exporter just fine:

package Foo; use strict; use warnings; use Carp; my %subs = ( subA => _gen_tr('abc' => 'xyz'), subB => _gen_tr('ijk' => 'qrs'), ); $subs{reverse($_)} = $subs{$_} for keys %subs; # Stand-in example for +aliases no strict 'refs'; *$_ = $subs{$_} for keys %subs; require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = keys %subs; sub _gen_tr { /^\w+$/ or confess "Non-word characters in argument: <$_>" for @_; eval "sub { shift =~ tr/$_[0]/$_[1]/r }" } 1;

The above works fine; all subs and their aliases are exported as expected (passes test code at the end of this post).

But when I replace the require Exporter; our @ISA ...; our @EXPORT_OK ...; lines with a similar Exporter::Easy incantation:

use Exporter::Easy ( OK => [ keys %subs ], TAGS => [ all => [ keys %subs ], ], );

Code using Foo sees "subA" is not exported by the Foo module, whether I use Foo ':all' or specify subA directly. I've even tried wrapping the exports and actual %subs initialization in a BEGIN block, but that did not make a difference. Hardcoding the sub names directly in the OK => [ ... ] or all => [ ... ] lines does of course work, but that's exactly what I'm trying to avoid doing.

Why Exporter::Easy? One reason is, I like it. The "real" reason is, my full code has more tags and more complex exports. I can do what I want with Exporter, but it's ugly. I'm willing to consider other Exporter::* modules if Exporter::Easy can't handle it. Or, I suppose, to suck it up and use Exporter if there's no other way.

So how would you do it? $cake->have->eat;

Test code:

use strict; use warnings; use Test::More; # Pick one: #use Foo qw/subA subB Abus Bbus/; use Foo ':all'; is subA('abra-cadabra'), 'xyrx-zxdxyrx'; is subB('i like stuff'), 'q lqse stuff'; is Abus('abra-cadabra'), 'xyrx-zxdxyrx'; is Bbus('i like stuff'), 'q lqse stuff'; done_testing;

In reply to Dynamic exports with Exporter::Easy by wanna_code_perl

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.