11 Stimmen

Wie kann ich in Perl herausfinden, ob meine Datei als Modul verwendet oder als Skript ausgeführt wird?

Nehmen wir an, ich habe eine Perl-Datei, in der es Teile gibt, die ich nur ausführen muss, wenn ich als Skript aufgerufen werde. Ich erinnere mich, vor einiger Zeit gelesen zu haben, dass man diese Teile in eine main()-Methode einbinden und eine

main() unless(<some condition which tests if I'm being used as a module>);

Aber ich habe vergessen, was die Bedingung war. Eine Suche bei Google hat nichts ergeben. Kann mir jemand sagen, wo ich danach suchen soll?

16voto

Sinan Ünür Punkte 114993

Wenn die Datei als Skript aufgerufen wird, gibt es keine Anrufer damit Sie es verwenden können:

main() unless caller;

Ver brian d foy 's Erklärung .

#!/usr/bin/perl

use strict;
use warnings;

main() unless caller;

sub main {
    my $obj = MyClass->new;
    $obj->hello;
}

package MyClass;

use strict;
use warnings;

sub new { bless {} => shift };

sub hello { print "Hello World\n" }

no warnings 'void';
"MyClass"

Sortie :

C:\Temp> perl MyClass.pm
Hello World

Verwendung aus einem anderen Skript:

C:\Temp\> cat mytest.pl
#!/usr/bin/perl

use strict;
use warnings;

use MyClass;

my $obj = MyClass->new;
$obj->hello;

Sortie :

C:\Temp> mytest.pl
Hello World

0 Stimmen

Das ist wirklich hilfreich. Danke für den Link.

0 Stimmen

Was ist mit perl -MMyClass -e' ... ' ?

0 Stimmen

@Brad Gilber Wenn MyClass.pm auf diese Weise geschrieben ist, perl MyClass.pm tut das Gleiche wie perl -MMyClass -e 'main()'

7voto

brian d foy Punkte 124323

Ich nenne diese Dinge ursprünglich "modulinos" in meinem Skripte als Module Artikel für Das Perl Journal (jetzt Dr. Dobbs ). Googeln Sie diesen Begriff und Sie erhalten die richtigen Ressourcen. Sinan hat bereits auf meine Entwicklungsquellen für eines meiner Bücher verwiesen, in denen ich darüber spreche. Das könnte Ihnen auch gefallen Wie ein Skript zu einem Modul wird .

2voto

jrockway Punkte 40754

Es ist besser, dies nicht zu tun und stattdessen einen strukturierten Ansatz zu wählen wie MooseX::Runnable .

Ihre Klasse wird wie folgt aussehen:

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;
    }
}

Jetzt haben Sie eine Klasse, die Sie problemlos in Ihrem Programm verwenden können:

my $finder = Get::Me::Data->new( database => $dbh );
$finder->get_data('jrockway');

Innerhalb eines interaktiven Skripts, das größer ist als die obige "run"-Methode:

...
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.";
...

Wenn Sie das allein machen wollen, können Sie das sagen:

$ 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>

Beachten Sie, wie wenig Code Sie geschrieben haben und wie flexibel die resultierende Klasse ist. "main if !caller" ist nett, aber warum sich die Mühe machen, wenn man es besser machen kann?

(MX::Runnable verfügt übrigens über Plugins, mit denen Sie die Anzahl der angezeigten Debugging-Ausgaben erhöhen, Ihre Anwendung neu starten können, wenn sich der Code ändert, die Anwendung persistent machen, sie im Profiler ausführen können usw.)

0 Stimmen

+1 für das Zeigen eines Elch-Weges. Ich habe immer noch nicht die Investition getätigt, um in diese Denkweise zu gelangen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X