use Smart::Commentsをソースに書かずに有効にする方法

Filter::Simple使わずにGlobalSmartComments::importで全部やればできますね。ということで後でちょっとやってます。

というわけでやってみた。多分これで終わり。力技過ぎてつまらなくなってきました。
頭良い人がすごくPerlらしい方法でやってくれると思います。っていうか実はすでにFilter::Global的なものがあったりします?

使い方ですが、例えばこんなFoo.pm

package Foo;
use Foo::Bar;

### This is Foo...

sub run {
    ### This is Foo#run...
}
1;

と、こんなFoo/Bar.pm

package Foo::Bar;

### This is Foo-Bar...

1;

と、こんなmain.pl

use Foo;
Foo->run;

があるとき、こんな風にFoo,Foo::Barを指定するとFoo,Foo::BarでSmart::Commentsが有効になります。

% perl -MSmart::Comments::Global=Foo,Foo::Bar main.pl

### This is Foo-Bar...

### This is Foo...

### This is Foo#run...

もちろんFooしか指定しなければFoo::Barでは有効にならず「### This is Foo-Bar...」は出ません。

main.plをこんな感じ

use Smart::Comments::Global qw(Foo Foo::Bar);
use Foo;
Foo->run;

にしても良いのですが、use Smart::Comments::Global以降の行にしか効果はありませんので最初に書く必要があります。

ソースはこんなSmart/Comments/Global.pm

package Smart::Comments::Global;
use strict;
use warnings;

use Fatal qw(open);
use File::Path;

my $inc = '/tmp/SmartCommentsGlobal';

sub import {
    my $class = shift;

    rmtree( [$inc] );
    mkpath( [$inc] );
    unshift @INC, $inc;

    foreach my $module (@_) {
        my $srcfile = `perldoc -mT $module`;
        chomp $srcfile;
        next if !$srcfile;

        my ( $destdir, $filename ) = $module =~ /(.*?)([^:]+)$/msx;
        $filename .= '.pm';
        $destdir =~ s{::}{/}gmsx;
        $destdir = $inc . q{/} . $destdir;

        my $destpath = $destdir . q{/} . $filename;

        mkpath( [$destdir] );

        open my $fh, q{>}, $destpath;
        print {$fh} "use Smart::Comments;\n";
        print {$fh} $srcfile;
        close $fh;
    }
    return;
}

1;