2010-07-23 9 views
0

J'essaie juste d'apprendre un peu de Perl, donc je passe par une fonction juste pour avoir une bonne compréhension de la langue. Quelqu'un pourrait-il m'expliquer ce que cette fonction fait exactement?Que fait cette fonction Perl?

#! /usr/bin/perl 
use strict; 

my %hash; 

&Parse('first.txt'); 
&Parse('second.txt'); 

my $outputpath = 'output.txt'; 
unlink ($outputpath); 
open (OUTPUT, ">>$outputpath") || die "Failed to open OUTPUT ($outputpath) - $!"; 
print OUTPUT "$_ \t" . join("\t", @{$hash{$_}}) . "\n" foreach (sort keys %hash); 
close (OUTPUT) || die "Failed to close OUTPUT ($outputpath) - $!"; 

sub Parse { 
    my $inputpath = shift; 
    open (INPUT, "<$inputpath") || die "Failed to open INPUT ($inputpath) - $!"; 
    while (<INPUT>) { 
     chomp; 
     my @row = split(/\t/, $_); 
     my $col1 = $row[0]; 
     shift @row; 
     push(@{$hash{$col1}}, @row); 
    } 
    close (INPUT) || die "Failed to close INPUT ($inputpath) - $!"; 
    return 1; 
} 

Je suis plus intéressé par shift et push et chomp.

+1

http://p3rl.org/shift http://p3rl.org/push http://p3rl.org/chomp – daxim

+0

@Svante: pour éviter les commentaires inutiles comme celui que vous avez posté ci-dessus. Comment cela aide-t-il le PO? Peut-être qu'il ne peut pas trouver le manuel, ou ne peut pas trouver où dans le manuel pour regarder. – Konerak

+0

Je suppose qu'on peut dériver de ce que quatre lettres j'avais posté. :) – Svante

Répondre

4

Modifier: affiché un code supplémentaire, je vais commenter aussi.

#!/usr/bin/perl 
#The first line (has to be first, hence this comment comes after) allows the linux shell to know 
#this is a perl program, and to call perl to execute it. 

#use strict: allow stricter checking of perl syntax. You should always do this. 
use strict; 

#declare a global variable called hash - not a very good name... 
my %hash; 

#call the method with 'first.txt' as argument 
&Parse('first.txt'); 
&Parse('second.txt'); #same thing, different parameter 


my $outputpath = 'output.txt'; 

#destroy the file declared above if it exists 
unlink ($outputpath); 

# open the file for append (could simple have opened for output and not used the unlink above...) 
open (OUTPUT, ">>$outputpath") || die "Failed to open OUTPUT ($outputpath) - $!"; 

#print a line to output 
#the line comes from a foreach loop 
#the foreach loop runs over the hash, sorted by key 
#each hash entry contains an array, this array is converted by a string using the JOIN function 
# the join function will paste the elements of the array into a string, seperated by a tab 
print OUTPUT "$_ \t" . join("\t", @{$hash{$_}}) . "\n" foreach (sort keys %hash); 

#Close the outputfile 
close (OUTPUT) || die "Failed to close OUTPUT ($outputpath) - $!"; 

Ce programme a probablement été écrit il y a quelque temps - moderne Perl est un peu différent et a quelques bonnes pratiques qui ne sont pas encore là. N'utilisez pas cela comme un exemple pour écrire Perl. Peut-être Ether réécrira pour vous, si vous sourire bien :)

#declare a sub 
sub Parse { 
    # the parameters given to a sub are stored in @_. 
    #shift without arguments takes the first element from @_ 
    my $inputpath = shift; 
    #opens the file "inputpath" into fileglob INPUT. 
    #If this fails, quit with an error message 
    open (INPUT, "<$inputpath") || die "Failed to open INPUT ($inputpath) - $!"; 

    #loop over the file one line at the time, putting each line in $_ 
    while (<INPUT>) { 

     #chop = remove last character. chomp = remove last character if it is a CRLF. 
     #Without arguments, works on $_ 
     chomp; 

     #split the $_ variable (containing the row) 
     #into an array based on the tab character 
     my @row = split(/\t/, $_); 

     # take the first element into col1 
     my $col1 = $row[0]; 

     # shift it (remove the first element) 
     shift @row; 

     # actually both rows above can be just written as one statement: 
     my $col1 = shift @row; 

     #the $hash variable is probably a global hashref defined somewhere above... 
     #the $hash hashref now contains a bucket named with the 'col1' value 
     # the value of that bucket is the array of the row we just read 
     push(@{$hash{$col1}}, @row); 

     # end the while loop 
    } 

    #close the file or die 
    close (INPUT) || die "Failed to close INPUT ($inputpath) - $!"; 

    #end the method 
    return 1; 
} 
+0

c'est une meilleure explication que je peux espérer. Merci – Vijay

+0

Maintenant j'ai collé le programme complet. Pourriez-vous également expliquer au sujet de la déclaration d'impression? – Vijay

2

Si vous avez une installation de perl sain d'esprit de la ligne de commande suivante commandes contribuera à:

perldoc -f shift 
perldoc -f push 
perldoc -f chomp 

Vous aimerez aussi:

perldoc perlfunc 
perldoc perlvar 

ne manquez pas la partie perlvar au sujet $_ ou vous obtiendrez jamais ce que Perl est sur le point.

Vous remarquerez progressivement que perl n'est pas orienté objet, il supporte les objets, mais c'est une implémentation plutôt étrange. Perl est plus orienté vers le travail orienté et le travail est généralement lié à l'extraction ou à la traduction d'une sorte de jeu de données.

Perl un liners sont les plus puissantes lignes de commande vous jamais écrire:

perl -pe 's/(\d*)/$1*10/ge' 

Découvrez les -p, -e, -n et -i commutateurs perldoc perlrun

(C'est l'une des principales raisons pour Perl 6 a été prévu comme réécriture majeure, seulement maintenant il a été dans les travaux depuis toujours et devrait sortir le lendemain Duke Nukem Forever)

shift de toute façon est comme de python some_array.pop(1) ou javascript de some_array.shift(), etc.

push est comme python de some_array.append(junk) ou javascript de some_array.push(more_junk), etc.

chomp est vraiment la version multi-plateforme de chop: elle supprime le caractère de fin de ligne des lignes qui ont été lues depuis stdin. C'est une sorte de piraterie pour surmonter ce petit opérateur de diamant <> (vérifier perldoc perlop - section "Opérateurs d'E/S") défaut: diamond lit stdin ou un argument de ligne de commande ligne par ligne, mais il ne supprime pas le \n. (ni le \r\n)

chomp les supprime après cela. (chop supprime uniquement \n et laisse \r seul.)

+0

Un dernier mot d'avertissement: lire le perl * d'autres personnes (ou même le vôtre, après quelques semaines) * peut être une * douleur royale *, se concentrer sur des exemples délibérés et des manuels. La documentation Perl est la plus complète que j'ai jamais vue. – ZJR

+0

non, il ne lit pas Perl d'autres personnes. Il lit Perl par des gens qui ne savent pas comment faire du développement de logiciel, plus spécifiquement comment écrire du code lisible. Ces personnes écriraient du code illisible dans N'IMPORTE QUELLE langue. – DVK

+0

Désolé, j'ai lu des modules de base: révisés par des pairs, bien indentés, bien commentés, documentés, et testés à l'unité: mais il * encore * était une douleur. – ZJR