2009-07-15 13 views
10

Diyelim ki, bir betik olarak adlandırıldığımda çalıştırmam gereken parçalar olan bir Perl dosyası var. Ben bir ana() yönteminde bu parçaların da dahil vePerl'de, dosyamın modül olarak mı kullanılıyor veya komut dosyası olarak çalıştırılıyorsa nasıl öğrenebilirim?

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

yapmayı geri bazen okumuştum Ama durum ne olduğunu unuttum. Google'da arama yapmak, verimli bir şey ortaya koymadı. Birisi buna bakmak için doğru yere işaret edebilir mi? Dosya bir komut dosyası olarak çağrıldığında

cevap

15

, hiçbir caller böylece kullanabilirsiniz olacak:

main() unless caller; 

Bkz brian d foy 'ın 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" 

Çıktı: Başka komut kullanma

C:\Temp> perl MyClass.pm 
Hello World 

:

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

use strict; 
use warnings; 

use MyClass; 

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

Çıktı:

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

Bu gerçekten yararlıdır. Bağlantı için teşekkürler. – seth

+0

@seth Hoşgeldiniz. –

+0

Peki ya perl -MMyClass -e '...' '? –

2

Daha İyi Bunu yapmak ve bunun yerine gibi yapısal bir yaklaşım değil MooseX::Runnable.

gibi Sınıfınız görünecektir: sadece "kaçak daha büyük bir etkileşimli komut İçinde

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

: Bir kolayca programın içine kullanılabilecek sınıf var Şimdi

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

"yukarıdaki yöntem:

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

Sadece bunu bağımsız yapmak istiyorsanız, şunu söyleyebilirsiniz:

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

Ne kadar küçük kod yazdığınızı ve sonuçta ortaya çıkan sınıfın ne kadar esnek olduğuna dikkat edin. "ana if! arayan" güzel, ama daha iyi yapabileceğiniz zaman neden rahatsız?

(BTW, MX :: Runnable eklentileri vardır; dolayısıyla, gördüğünüz hata ayıklama çıktısının miktarını kolayca artırabilir, kod değiştiğinde uygulamanızı yeniden başlatır, uygulamayı kalıcı hale getirir, profilleyicide çalıştırır vb.)

+0

+1 ile örnekler gösteriyorum.Hala bu zihniyete girme yatırımını yapmadım. –

7

başlangıçta benim Scripts as Modules maddeye Perl Journal (şimdi Dr. Dobbs) böyle şeyler "modulinos" diyoruz. Google bu terim ve doğru kaynakları alırsınız. Sinan, zaten onun hakkında konuştuğum kitaplardan biri için gelişim kaynaklarına bağlanmıştır. Ayrıca How a Script Becomes a Module'u da beğenebilirsiniz.

İlgili konular