2015-04-08 2 views
4

J'ai lu ceci à propos perl:Quelle est la moyenne de « à la compilation » dans les scripts perl

Perl est un langage interprété et ne compile pas.

Et je vois aussi parler de at compile-time et at run-time.

Surtout quand je regarde pour l'utilisation de use et require, il montre une différence:

use charge normalement le module au moment de la compilation alors require ne au moment de l'exécution.

Donc, ma question est de savoir si Perl compile vraiment le script?
Quelle est la moyenne de 'at at compile-time' dans les scripts Perl?

Répondre

4

Perl compile avant de s'exécuter. Habituellement, c'est fait immédiatement avant. L'exécution perl -c effectuera une vérification de validité de code assez basique et mettra en évidence certaines classes d'erreurs (généralement dans mon cas, des points-virgules manquants).

De perlrun:

Après avoir localisé votre programme, Perl compile l'ensemble du programme à une forme interne. S'il y a des erreurs de compilation, l'exécution du programme n'est pas tentée. (Ceci est différent du script shell typique, qui peut être exécuté à mi-chemin avant de trouver une erreur de syntaxe.)

Cela inclut le chargement et la vérification de tous les modules importés pour les mêmes tests. Dans la plupart des cas est exactement ce que vous voulez - ces tests/erreurs sont habituellement montrent des arrêts, et ainsi de détection avant même de commencer à exécuter est une bonne chose.

Surtout quand vous use strict; et use warnings; votre code est prétraité pour un plus grand nombre d'erreurs. Il est fait au moment de la compilation, et il va avorter si quelque chose il a repéré.

Encore une fois, cela est généralement souhaitable - trébucher sur glitches à mi-chemin à travers un programme est généralement plus agaçant pour les trier, comme vous êtes potentiellement dans un état incohérent.

Cependant, comme vous le constatez, des éléments tels que les modules peuvent être très volumineux et il peut être utile de les charger à la volée. Perl peut redéfinir un tas de choses au fur et à mesure - si vous voulez vraiment, vous pouvez créer/changer des sous-routines dans votre code.

Les modifications apportées aux sous-programmes et leur validité ne peuvent jamais être effectuées au "moment de la compilation" en raison de ce que l'on appelle le problème d'état d'arrêt. Donc, vous chargez au moment de l'exécution, mais vous devez ensuite intégrer une vérification d'intégrité plus complète.

+3

Un grand nombre d'erreurs 'use strict;' et 'use warnings; 'sont réellement détectées au moment de l'exécution. (par exemple '$ x =" abc "; $ x -> {def}' et 'print undef;') – ikegami

2

Jetez un oeil à How a Perl 5 Program Works. Il indique que

Il existe deux phases distinctes d'exécution d'un programme Perl 5: l'heure de compilation et l'exécution.

Il décrit également la différence entre compile time et runtime.

5

Le code Perl est compilé avant d'être exécuté, mais pas pour le code machine. C'est un peu comme comment Java est compilé en code octet, mais le résultat est de plus haut niveau.

# B::Concise shows the opcode tree that results from compiling Perl code 

$ perl -MO=Concise,-exec -e'print("Hello, world!\n") for 1..3;' 
1 <0> enter 
2 <;> nextstate(main 1 -e:1) v:{ 
3 <0> pushmark s 
4 <$> const[IV 1] s 
5 <$> const[IV 3] s 
6 <#> gv[*_] s 
7 <{> enteriter(next->b last->e redo->8) lKS/8 
c <0> iter s 
d <|> and(other->8) vK/1 
8  <0> pushmark s 
9  <$> const[PV "Hello, world!\n"] s 
a  <@> print vK 
b  <0> unstack v 
      goto c 
e <2> leaveloop vK/2 
f <@> leave[1 ref] vKP/REFC 
-e syntax OK 

Lorsque Perl est demandé d'exécuter un fichier (car il a été passé à perl, require, do EXPR ou eval EXPR), il commence par Compile le fichier entier, exécute alors le code compilé juste.

Si use ou BEGIN se produit pendant la phase de compilation, l'instruction use ou BEGIN bloc est exécuté dès qu'il a terminé la compilation.

# -c causes the main program to be compiled but not executed. 

$ perl -c -E' 
    say "abc"; 
    BEGIN { say "def"; } 
    say "ghi"; 
' 
def 
-e syntax OK 

$ perl -E' 
    say "abc"; 
    BEGIN { say "def"; } 
    say "ghi"; 
' 
def 
abc 
ghi 

Certaines erreurs peuvent être détectées lors de la compilation.

$ perl -c -E'say "abc" "def";' 
String found where operator expected at -e line 1, near ""abc" "def"" 
     (Missing operator before "def"?) 
syntax error at -e line 1, near ""abc" "def"" 
-e had compilation errors. 

D'autres ne le peuvent pas.

$ perl -c -E'$x={}; $x->[0]' 
-e syntax OK 

$ perl -E'$x={}; $x->[0]' 
Not an ARRAY reference at -e line 1.