2009-09-12 23 views
5

Mam skrypt Perla (foo.pl), który ładuje Foo.pm z tego samego katalogu przy użyciu wymagają mechanizmu:Jak mogę rozpowszechniać moją aplikację Perl jako pojedynczy plik?

require "./Foo.pm"; 
... 
my $foo = new Foo::Bar; 

Foo.pm przylega do standardowego formatu module:

package Foo::Bar; 
... 
1; 

Zamiast dystrybuować moją aplikację jako dwa pliki (foo.pl i Foo.pm), chcę rozpowszechniać tylko jeden plik. Dokładniej chciałbym uczynić część Foo.pm częścią skryptu foo.pl.

Jak to osiągnąć?

trywialne podejście po prostu łączenie dwóch plików (CAT foo.pl Foo.pm foo2.pl>) nie działa.

Odpowiedz

3

Twój kod nie działa (choć byłoby pomocne podać komunikat o błędzie (-y), który odebrane), ponieważ próbowałeś użyć Foo :: Bar, zanim został on zdefiniowany. Spróbuj tego:

use strict; 
use warnings; 
my $foo = Foo::Bar->new(); 
# more code... 

# end code 

# begin definitions 
BEGIN { 
    package Foo::Bar; 
    use strict; 
    use warnings; 
    # definitions... 
    1; 

    package Foo::Baz; 
    # more stuff, if you need to define another class 
} 

Dodatki:

2

Ogólny schemat polegałby na zastąpieniu twojego "wymagaj ..." treścią tego, czego żądasz. Jest w tym coś więcej (BEGIN {} może być potrzebny), a ja nie jestem do końca pewien, co się w nim dzieje. Na pewno chcesz ją zautomatyzować.

Oto alternatywa: generuje pojedynczy plik wykonywalny, gdzie moduły zależą od pakowane są w środku za pomocą PAR/pp

+0

Hi wrang-wrang! Dzięki za wskazówki. Niestety tworzenie pliku wykonywalnego nie jest opcją, ponieważ ten sam skrypt będzie używany na wielu platformach. – knorv

+1

knorv: Jeśli nie ma żadnych modułów z komponentem XS/C/skompilowanym, PAR może tworzyć pliki .par, które są wieloplatformowe. NIE jest to binarny plik wykonywalny, jak w przypadku "pp -o foo.exe foo.pl". – tsee

4

Plik może zawierać wiele pakietów. Najpierw umieść swoją klasę, a następnie główny skrypt:

package Foo::Bar; 

sub new { 
    my $class = shift; 
    return bless {}, $class; 
} 

#... 

package main; 

my $foo = Foo::Bar->new(); 
print ref $foo; # Foo::Bar 
+3

Instrukcja 'pakiet' nie tworzy nowego zakresu, więc możesz użyć' {package Foo :: Bar; REST_OF_THE_CODE} 'aby nie dopuścić do przecieku między tymi dwoma pakietami. –

2

Masz już kilka dobrych odpowiedzi. Ponadto możliwe jest utworzenie modułu, który można uruchomić bezpośrednio jako skrypt.

package Foo; 

__PACKAGE__->run(@ARGV) unless caller(); 

sub run { 
    # Do stuff here if you are running the Foo.pm as 
    # a script rather than using it as a module. 
} 

Aby uzyskać dodatkowe informacje, patrz temat: brian d foy How a Script Becomes a Module.

5

Jeśli jesteś zainteresowany pakowania skryptu Perl w binarnym ze wszystkimi modułami to zależy włączone, można użyć PAR Packager:

pp -o binary_name foo.pl 
Powiązane problemy