2009-07-15 9 views
10

Załóżmy, że mam plik Perla, w którym są części, które muszę uruchomić tylko wtedy, gdy jestem nazywany jako skrypt. Pamiętam, jak kiedyś czytałem o włączaniu tych części w metodę main() i robieniu tego, co robiłem, ale nie pamiętałem, co to był warunek(). Wyszukiwanie w Google nie przyniosło niczego pożytecznego. Czy ktoś może wskazać właściwe miejsce, aby to poszukać?W Perlu, w jaki sposób mogę sprawdzić, czy mój plik jest używany jako moduł, czy uruchamiany jako skrypt?

Odpowiedz

15

Jeśli plik jest wywoływany jako skrypt, nie będzie caller więc można użyć:

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" 

wyjściowa:

C:\Temp> perl MyClass.pm 
Hello World 

Korzystanie z innego skryptu:

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

use strict; 
use warnings; 

use MyClass; 

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

wyjściowa:

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

To jest naprawdę pomocne. Dzięki za link. – seth

+0

@ Witam serdecznie. –

+0

Co z 'perl -MMyClass -e '...''? –

2

Lepiej tego nie robić, i zamiast wziąć uporządkowanego podejścia podobnego MooseX::Runnable.

Twoja klasa będzie wyglądać następująco:

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

Teraz masz klasy, który może być używany wewnątrz programu łatwo:

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

wewnątrz interaktywny skrypt, który jest większy niż tylko „w biegu "powyższa metoda:

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

Jeśli chcesz zrobić to samodzielnie, możesz powiedzieć:

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

Zauważ, jak napisałeś mały kod i jaka jest elastyczność tworzonej klasy. "main if! caller" jest fajny, ale po co zawracać sobie głowę, kiedy możesz zrobić coś lepszego?

(BTW, MX :: Runnable ma wtyczki, dzięki czemu można z łatwością zwiększyć ilość wyświetlanych wyników debugowania, ponownie uruchomić aplikację po zmianie kodu, uczynić aplikację stałą, uruchomić ją w programie profilującym itd.)

+0

+1 za pokazanie drogi łosia.Nadal nie zainwestowałem w ten sposób myślenia. –

7

nazywam te rzeczy "modulinos" pierwotnie w moim Scripts as Modules artykule Perl Journal (obecnie dr Dobbs). Google to określenie i masz odpowiednie zasoby. Sinan był już powiązany z moimi źródłami programistycznymi w jednej z moich książek, o której mówię. Może Ci się też spodobać How a Script Becomes a Module.

Powiązane problemy