2009-09-12 3 views
5

J'ai un script Perl (de foo.pl) qui se charge Foo.pm à partir du même répertoire en utilisant le mécanisme exigent:Comment puis-je distribuer mon application Perl en un seul fichier?

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

Le Foo.pm adhère au format module standard:

package Foo::Bar; 
... 
1; 

Plutôt que de distribuer mon application en deux fichiers (foo.pl et Foo.pm), j'aimerais distribuer un seul fichier. Plus spécifiquement, j'aimerais faire de Foo.pm une partie du script foo.pl.

Comment puis-je y parvenir?

L'approche triviale consistant simplement à fusionner les deux fichiers (cat foo.pl Foo.pm> foo2.pl) ne fonctionne pas.

Répondre

3

Votre code ne fonctionne pas (bien qu'il aurait été utile d'indiquer le message d'erreur (s) que vous reçu) parce que vous avez essayé d'utiliser Foo :: Bar avant d'avoir été défini. Essayez ceci:

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 
} 

ajouts:

2

Le schéma général serait de remplacer votre "require ..." avec le contenu de ce que vous exigez. Il y a plus que cela (BEGIN {} peut être nécessaire), et je ne suis pas sûr de ce que cela implique. Pour sûr, vous voudriez l'automatiser.

est ici une alternative: générer un fichier exécutable unique où les modules dont vous dépendez sont emballés à l'intérieur à l'aide PAR/pp

+0

Salut wrang-wrang! Merci pour les conseils. Malheureusement, la création d'un exécutable n'est pas une option puisque le même script sera utilisé sur plusieurs plates-formes. – knorv

+1

knorv: Si vous n'incluez aucun module avec un composant compilé XS/C, PAR peut créer des fichiers .par multi-plateformes. Ce n'est pas un exécutable binaire comme avec "pp -o foo.exe foo.pl". – tsee

4

Un fichier peut contenir plusieurs paquets. Mettez votre classe en premier, suivi du script principal:

package Foo::Bar; 

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

#... 

package main; 

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

L'instruction 'package' ne crée pas de nouvelle portée, vous pouvez donc utiliser' {package Foo :: Bar; REST_OF_THE_CODE} 'pour éviter que les choses fuient entre les deux paquets. –

2

Vous avez déjà quelques bonnes réponses. En outre, il est possible de créer un module qui peut être exécuté directement en tant que script.

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

Pour plus de détails, voir brian d foy de How a Script Becomes a Module.

5

Si vous êtes intéressé à emballer votre script Perl dans un binaire avec tous les modules dont il dépend inclus, vous pouvez utiliser PAR Packager:

pp -o binary_name foo.pl 
Questions connexes