スクリプトとして呼び出されたときにのみ実行する必要がある部分がある Perl ファイルがあるとします。これらの部分を main() メソッドに含めて、
main() unless(<some condition which tests if I'm being used as a module>);
でもどんな状態だったか忘れました。Google で検索しても、実りあるものは何も見つかりませんでした。誰かがこれを探すのに適切な場所を指摘できますか?
私はこれらのことを「モジュールとしてのスクリプト」と呼んでいますが、もともとはPerl Journal (現在はDr. Dobbs ) のScripts as Modules記事で使用されていました。その用語をグーグルで検索すると、適切なリソースが得られます。Sinan は、私がそれについて語っている私の本の 1 つで、私の開発ソースに既にリンクしています。スクリプトがモジュールになる方法も好きかもしれません。
これを行うのではなく、MooseX::Runnableのような構造化されたアプローチを採用することをお勧めします。
クラスは次のようになります。
class Get::Me::Data with (MooseX::Runnable, MooseX::Getopt) {
has 'dsn' => (
is => 'ro',
isa => 'Str',
documentation => 'Database to connect to',
);
has 'database' => (
is => 'ro',
traits => ['NoGetopt'],
lazy_build => 1,
);
method _build_database {
Database->connect($self->dsn);
}
method get_data(Str $for_person){
return $database->search({ person => $for_person });
}
method run(Str $for_person?) {
if(!$defined $for_person){
print "Type the person you are looking for: ";
$for_person = <>;
chomp $for_person;
}
my @data = $self->get_data($for_person);
if(!@data){
say "No data found for $for_person";
return 1;
}
for my $data (@data){
say $data->format;
}
return 0;
}
}
これで、プログラム内で簡単に使用できるクラスができました。
my $finder = Get::Me::Data->new( database => $dbh );
$finder->get_data('jrockway');
上記の「実行」メソッドよりも大きな対話型スクリプト内:
...
my $finder = Get::Me::Data->new( dsn => 'person_database' );
$finder->run('jrockway') and die 'Failure'; # and because "0" is success
say "All done with Get::Me::Data.";
...
これをスタンドアロンで行いたい場合は、次のように言えます。
$ mx-run Get::Me::Data --help
Usage: mx-run ... [arguments]
--dsn Database to connect to
$ mx-run Get::Me::Data --dsn person_database
Type the person you are looking for: jrockway
<data>
$ mx-run Get::Me::Data --dsn person_database jrockway
<data>
作成したコードがいかに少ないか、そして結果のクラスがいかに柔軟であるかに注目してください。「main if !caller」は素晴らしいですが、もっとうまくやれるのになぜわざわざするのでしょうか?
(ところで、MX::Runnable にはプラグインがあります。そのため、表示されるデバッグ出力の量を簡単に増やしたり、コードが変更されたときにアプリを再起動したり、アプリを永続化したり、プロファイラーで実行したりできます。)