実行時に動的にパッチをあてる


404 Blog Not Found:perl - パッチなしでパッチする

動的にサブルーチンを書き換える話。


はてなブックマーク > 404 Blog Not Found:perl - パッチなしでパッチする

2007年04月09日 kazuhooku perl source filter でロード時にパッチあてるとかできないのかな


そんな感じのをちょこっと作ってみた。モジュール名は適当。

package Module::Patch;
use strict;
use warnings;
use base qw(Exporter);

use Text::Patch;

our $VERSION = '0.01';
our @EXPORT = qw(use_patch require_patch);

sub use_patch {
    my %param = @_;
    require_patch(@_);
    my @args = exists $param{args} ? @{$param{args}} : ();
    $param{module}->import(@args);
}

sub require_patch {
    my %param = @_;
    die 'paramater module required.' unless exists $param{module};
    die 'paramater diff or diff_file required.'
        if !exists $param{diff} and !exists $param{diff_file};
    my $path = $param{module};
    $path =~ s!::!/!g;
    $path .= '.pm';
    my $file;
    for my $dir (@INC) {
        my $check = "$dir/$path";
        $file = $check if -f $check;
    }
    die "cannot find module $param{module}" unless $file;
    open my $fh, '<', $file or die "cannot open file $file.";
    my $src = do { local $/; <$fh> };
    close $fh;
    unless (exists $param{diff}) {
        open $fh, '<', $param{diff_file}
            or die "cannot open the diff_file $param{diff_file}.";
        $param{diff} = do { local $/; <$fh> };
        close $fh;
    }
    my $output = patch($src, $param{diff}, STYLE => $param{style} || 'Unified');
    eval $output or die "cannot require $param{module} with patch.";
    1;
}

1;
__END__


こんな感じで使う。

use Module::Patch;
use_patch(
    module => 'ModuleName',
    diff   => $diff, # or diff_file => $file
);

モジュールにパッチをあててuseできると。


useが必要な箇所でいちいちこれを書かないといけないので、いろんなところでこれを書くのはきついなぁ。