2009-07-15 4 views
10

내가 스크립트로 호출되었을 때만 실행해야하는 부분이있는 Perl 파일이 있다고 가정 해 봅니다. 언젠가는 main() 메서드에서 이러한 부분을 포함하는 것에 대해 다시 읽는 것을 기억합니다.Perl에서 내 파일이 모듈로 사용되거나 스크립트로 실행되는지 어떻게 알 수 있습니까?

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

그러나 조건이 무엇인지 잊어 버렸습니다. 구글 검색은 결실을 맺지 못했습니다. 누군가가 이것을 찾을 수있는 적절한 장소를 지적 할 수 있습니까? 파일을 스크립트로 호출하면

답변

15

, 더 caller 그래서 당신이 사용할 수있을 것입니다 :

main() unless caller; 

참조 brian d foyexplanation.

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

출력 : 다른 스크립트에서 사용

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; 

출력 :

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

정말 도움이됩니다. 링크를 가져 주셔서 감사합니다. – seth

+0

@seth 여러분을 환영합니다. –

+0

'perl -MyyClass -e '...''는 어떨까요? –

2

더 나은이 작업을 수행하고, 대신 같은 구조적인 접근을하지 않도록 MooseX::Runnable.

같은 클래스가 보일 것이다 : 바로 "실행보다 큰 대화 형 스크립트 내부

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

: 당신은 쉽게 프로그램 내에서 사용할 수있는 클래스가 이제

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

위의 방법 :

... 
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"는 좋지만 더 잘할 수있을 때 왜 귀찮은가?

(BTW, MX :: Runnable에는 플러그인이 있으므로 표시되는 디버깅 출력을 쉽게 늘릴 수 있으며 코드가 변경되면 앱을 다시 시작하고 앱을 영구적으로 유지 한 다음 프로파일 러에서 실행하는 등)

+0

+1 무스 방식을 보여줍니다.나는 아직도 그 사고 방식에 들어가기 위해 투자를하지 않았다. –

7

나는 원래 Scripts as Modules 기사 펄 저널 (지금 박사 돕 스는)에서 이러한 것들을 "modulinos"를 호출합니다. Google은 그 용어를 사용하고 올바른 리소스를 얻습니다. 신안은 이미 나의 책 중 하나에 대한 나의 개발 원천과 연결되어있다. How a Script Becomes a Module을 좋아할 수도 있습니다.