2009-07-15 3 views
10

Angenommen, ich habe eine Perl-Datei, in der Teile enthalten sind, die ich nur ausführen muss, wenn ich als Skript aufgerufen werde. Ich erinnere mich, irgendwann wieder über die Teile in einer Methode main() einschließlich undWie kann ich in Perl herausfinden, ob meine Datei als Modul verwendet oder als Skript ausgeführt wird?

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

zu tun, aber ich habe vergessen, was die Bedingung war. Die Suche nach Google hat nichts fruchtbares ergeben. Kann jemand auf den richtigen Ort hinweisen, um danach zu suchen?

Antwort

15

Wenn die Datei als Skript aufgerufen wird, wird es keine caller so können Sie verwenden:

main() unless caller; 

See brian d foy ‚s explanation.

#!/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" 

Ausgang:

C:\Temp> perl MyClass.pm 
Hello World 

von einem anderen Skript:

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

use strict; 
use warnings; 

use MyClass; 

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

Ausgang:

C:\Temp> mytest.pl 
Hello World 
+0

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

+0

@seth Sie sind willkommen. –

+0

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

2

Besser dies nicht zu tun, und stattdessen einen strukturierten Ansatz 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([email protected]){ 
      say "No data found for $for_person"; 
      return 1; 
     } 

     for my $data (@data){ 
      say $data->format; 
     } 

     return 0; 
    } 
} 

Jetzt haben Sie eine Klasse, die leicht in Ihrem Programm verwendet werden können:

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

Innerhalb eines interaktiven Skript, das größer als nur die „run ist "Methode oben:

... 
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 nur dieses Standalone tun möchten, können Sie sagen:

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

(BTW, MX :: Runnable hat Plugins; so können Sie einfach die Menge der Debugging-Ausgabe erhöhen, starten Sie Ihre App, wenn der Code ändert, machen Sie die App persistent, führen Sie es im Profiler, etc.)

+0

+1 für einen Moose Weg.Ich habe immer noch nicht investiert, um in diese Denkweise zu kommen. –

7

ich nenne diese Dinge "modulinos" ursprünglich in meinem Scripts as Modules Artikel für Das Perl Journal (jetzt Dr. Dobbs). Google diesen Begriff und Sie erhalten die richtigen Ressourcen. Sinan hat bereits mit meinen Entwicklungsquellen für eines meiner Bücher in Verbindung gebracht, wo ich darüber rede. Sie könnten auch mögen How a Script Becomes a Module.

Verwandte Themen