fc2ブログ

SelfArchive

最近テンプレートだのCSSだのをheredocに書くことが多くなったような気がするので、こんなモジュール作ってみた。

== SelfArchive.pm ==

package SelfArchive;

use strict;
use warnings;
use base qw/Class::Accessor::Fast/;
use Carp;

our $VERSION = '0.1';

__PACKAGE__->mk_accessors(qw/ sep files /);

sub new {
    my $class = shift;
    my $self = bless { sep => qr/^_{4,}\s+([\w.]+)\s+_+\n/m , @_ }, $class;
    my $caller = (caller)[0];
    no strict 'refs';
    my $fh = *{"$caller\::DATA"};
    my $data = '';
    my $line;
    local($/) = "\n";
    while (defined($line = <$fh>) && $line !~ /^__END__/) {
	$data .= $line;
    }
    my (undef, %files) = split($self->sep, $data);
    $self->files(\%files);
    return $self;
}

sub get {
    my ($self, $name) = @_;
    return $self->files->{$name};
}

sub extract_to_file {
    my ($self, $name, $out) = @_;
    open(my $fh, '>', $out) or die "$out: $!";
    print $fh $self->get($name);
    close($fh);
}

1;
__END__

=head1 NAME

SelfArchive - archive files in DATA section

=head1 SYNOPSIS

    use SelfArchive;

    my $sa = SelfArchive->new;
    my $template = $sa->get('index.tt); # get archived data as string
    $sa->extrace_to_file('mysite.css', '/tmp/index.css'); # save to a file
      :
      :

    __DATA__
    _____ index.tt _____
    <title>[% your.title %]</title>
    <h1>[% your.header %]</h1>
    _____ mysite.css _____
    h1 { font-size: 1.3em }
    __END__

    SelfArchive ignores this

=head1 DESCRIPTION

Archived multiple files in DATA section.

Files are separated by C<sep> regexp. C<sep> must have exactly one
captured expression, which is treated as a file name.

Default C<sep> is qr/^={4,}\s+([\w.]+)\s+=+\n/m.

=head1 INTERFACE

=head2 new

Constructor. Optional C<sep> attribute is a regexp of file separator.

  my $sa = new({ sep => qr/^----(\w+)----/m })

=head2 get

Return the specified file contents in the archive.

  my $content = $sa->get('index.tt');

=head2 extract_to_file

Save the specified file contents in the archive to a normal file.

  $sa->extract_to_file('index.tt', '/tmp/mytemplate.tt');
  # /tmp/mytemplate.tt is created

=cut

なんかどっかで見たことがある様な気がしなくもない。

区切りが = だと、podと間違われることがあるらしいので _ にした。