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

O wise and benevolent masters, I humbly lay my unworthy question at your feet:

My module exports a compile-time constant to its caller. It's important that it be a compile-time constant so the optimizer can take advantage of that. So I create it thusly (in my import):

eval "sub ${caller_package}::DEBUG () { $debug_value }";

The problem is that now Pod::Coverage calls DEBUG a naked subroutine in the caller, which of course fails the ubiquitous Test::Pod::Coverage tests. I decided to look and see how Pod::Coverage was figuring out whether a sub was imported or not, and discovered this bit of Black Magic:

# see if said method wasn't just imported from elsewhere my $glob = do { no strict 'refs'; \*{$sym} }; my $o = B::svref_2object($glob); # in 5.005 this flag is not exposed via B, though it exists my $imported_cv = eval { B::GVf_IMPORTED_CV() } || 0x80; next if $o->GvFLAGS & $imported_cv;

After my head stopped hurting, I decided to just give up and change my code so it really is imported, like so:

eval "sub DEBUG () { $debug_value }"; *{ join('::', $caller_package, 'DEBUG') } = \&DEBUG;

Sure enough, that shuts up Pod::Coverage, but now my compile-time constant isn't a compile-time constant any more. :-/

Now, obviously I know that I can just tell Test::Pod::Coverage to ignore that routine, but I don't think it's reasonable to tell anyone who uses my module to do so. I'm willing to set that bitflag that Pod::Coverage is relying on manually, but I have no idea how to go about that ... that's perlguts stuff, which is a bit beyond my skill level (although I'm willing to attempt it, if anyone could point me in the right direction).

Any thoughts on the best way to get Pod::Coverage to ignore my routine when it's exported to other packages?

Replies are listed 'Best First'.
Re: How to get Pod::Coverage to stop calling my export naked (closure)
by tye (Sage) on Feb 04, 2012 at 20:12 UTC
    sub import { # ... { no strict 'refs'; *{$pkg."::DEBUG"} = sub() { $debug }; } # ... }

    - tye        

      You, sir, are brilliant.

      That was so much simpler than I expected ... thank you so much for the super-quick turnaround.

      Note that if the module that is importing DEBUG uses namespace::autoclean or similar (as is common in the Moose world these days), then the DEBUG function will not be callable as an object or class method. (Though it should still be called OK as a function.)

      A workaround for that is to use Sub::Name

      use Sub::Name qw/subname/; sub import { # ... my $exp = $pkg."::DEBUG"; { no strict 'refs'; *{$exp} = subname $exp => sub() { $debug }; } # ... }
Re: How to get Pod::Coverage to stop calling my export naked
by educated_foo (Vicar) on Feb 05, 2012 at 04:48 UTC
    I would suggest not using Pod::Coverage. When you have to change clear and working code to placate a style checker, the fault lies with the style checker, not your code.
Re: How to get Pod::Coverage to stop calling my export naked
by LanX (Saint) on Feb 05, 2012 at 12:00 UTC
    I never used this module, but after reading the doc I'm irritated...

    Did you try to categorize DEBUG as private or also_private?

    from Pod::Coverage

    Methods Pod::Coverage->new(package => $package) Creates a new Pod::Coverage object. package the name of the package to analyse private an array of regexen which define what symbols are regarded as private (and so need not be documented) ... also_private items are appended to the private list

    I agree with educated_foo that Pod::Coverage shouldn't be an installation test, but rather a part of the release/development process.

    Cheers Rolf

      Thanks for all the suggestions, guys, but I think you misunderstood the problem. The Pod::Coverage problem is not with my module; it's in the module that uses my module. I can't document the constant in my user's POD, I can't make the user declare it private and I can't force them not to use Pod::Coverage. I wouldn't even get very far advising them not to use it: there are all sorts of recommendations out there from very smart people telling them to do it, and Dist::Zilla even includes a Test::Pod::Coverage test in its release tests, if you turn that feature on.

      tye's answer was 100% correct and solved my problem neatly and completely. ++ to him.

Re: How to get Pod::Coverage to stop calling my export naked
by Xiong (Hermit) on Feb 05, 2012 at 04:16 UTC

    Um... what if you wrote POD to cover it?

    I'm not the guy you kill, I'm the guy you buy. —Michael Clayton