Προεπιλεγμένες μεταβλητές#
Δύο μεταβλητές κρατούν τους σιωπηρούς τελεστέους της Perl. Η $_ είναι το προεπιλεγμένο βαθμωτό που αμέτρητες ενσωματωμένες διαβάζουν όταν κληθούν χωρίς όρισμα. Η @_ είναι ο πίνακας ορισμάτων κάθε υπορουτίνας. Μαζί ευθύνονται για τις περισσότερες εκπλήξεις «από πού ήρθε αυτή η τιμή;» σε κώδικα Perl.
$_ - το προεπιλεγμένο βαθμωτό#
Η $_ είναι το θέμα: η τιμή για την οποία γίνεται λόγος αυτή τη στιγμή. Ένα τεράστιο πλήθος ενσωματωμένων της Perl τη συμβουλεύεται όταν κληθεί χωρίς ρητό όρισμα:
for my $line (<$fh>) {
chomp; # chomp $line - but $line was aliased to $_
print if /\bERROR\b/; # print $_ if $_ =~ /\bERROR\b/
}
Η πλήρης λίστα ενσωματωμένων που χρησιμοποιούν εξ ορισμού τη $_ περιλαμβάνει chomp, chop, lc, lcfirst, length, pos, print, printf, quotemeta, say, split (προεπιλεγμένο μοτίβο), study, uc, ucfirst, unlink, τους τελεστές m// και s///, τον τελεστή tr///, και τους τελεστές ελέγχου αρχείου <>/-X. Οι σελίδες λεπτομερειών τους κατονομάζουν τη $_ ως προεπιλογή· αυτή η σελίδα είναι η κανονική περιγραφή.
Ψευδωνυμοποίηση μέσα σε for και while#
Ο βρόχος for (και foreach) ψευδωνυμεί τη $_ σε κάθε στοιχείο της λίστας, διαδοχικά:
my @items = (1, 2, 3);
for (@items) {
$_ *= 2; # mutates @items in place
}
# @items is now (2, 4, 6)
Η τροποποίηση της $_ μέσα στον βρόχο τροποποιεί το ίδιο το στοιχείο λίστας. Αυτή είναι πανομοιότυπη συμπεριφορά με τις map, grep, any, all - και τις first και reduce από τη List::Util.
Η while (<$fh>) δεν ψευδωνυμεί - διαβάζει κάθε γραμμή στη $_ ως νέο αντίγραφο. Δεν μπορείτε να γράψετε πίσω στο αρχείο αναθέτοντας στη $_ μέσα σε βρόχο while (<$fh>).
Τοπικοποίηση $_#
Μια υπορουτίνα που θέλει τη δική της $_ χωρίς να διαταράξει αυτή του καλούντος πρέπει να την κάνει local:
sub categorise {
local $_ = shift; # decouple from caller's $_
return 'small' if /^\d{1,3}$/;
return 'medium' if /^\d{4,6}$/;
return 'large';
}
my @sizes;
for ('5', '12345', '999999999') {
push @sizes, categorise($_); # caller's $_ stays the loop alias
}
Χωρίς τη local, η κλήση categorise() με shift θα λειτουργούσε - αλλά κάθε =~, /.../, ή chomp μέσα σε αυτήν θα διάβαζε ή θα έγραφε σιωπηρά το ψευδώνυμο βρόχου, σπάζοντας την επανάληψη του καλούντος.
Η $_ ως lvalue#
Η $_ είναι μια πραγματική βαθμωτή μεταβλητή· μπορείτε να αναθέσετε σε αυτήν, να πάρετε αναφορά σε αυτήν, και να τη μεταβιβάσετε ως lvalue:
$_ = 'hello';
chomp; # nothing to chomp; $_ unchanged
s/l/L/g; # $_ is now 'heLLo'
my $ref = \$_; # \$_ is the alias's address
$$ref = 'goodbye'; # mutates whatever $_ is currently bound to
Προσέξτε ότι το δεύτερο $$ref θα γράψει σε ό,τι είναι η $_ αυτή τη στιγμή - που μέσα σε βρόχο for είναι το τρέχον στοιχείο λίστας. Αναφορές στη $_ που λήφθηκαν εκτός βρόχου και χρησιμοποιούνται μέσα σε αυτόν σπάνια κάνουν αυτό που εννοούσε ο συγγραφέας.
Λεξιλογική $_#
Οι our $_ και my $_ ήταν πειραματικά χαρακτηριστικά που αφαιρέθηκαν. Η $_ είναι πάντα η καθολική πακέτου· χρησιμοποιήστε local $_ για απομόνωση.
@_ - ορίσματα υπορουτίνας#
Μέσα σε μια υπορουτίνα, η @_ είναι ο πίνακας ορισμάτων που μεταβιβάστηκαν σε αυτή την κλήση. Κάθε στοιχείο είναι ψευδώνυμο προς την έκφραση του καλούντος - η @_ δεν είναι αντίγραφο:
sub double {
$_[0] *= 2; # mutates the caller's variable
}
my $x = 5;
double($x);
# $x is now 10
Γι” αυτό οι περισσότερες subs ξεκινούν με my (...) = @_; - η αποσυσκευασία δημιουργεί αντίγραφα, μετά τα οποία η ρουτίνα δεν μπορεί κατά λάθος να τροποποιήσει την κατάσταση του καλούντος:
sub greet {
my ($name, $greeting) = @_; # decoupled from caller
$greeting //= 'Hello';
return "$greeting, $name!";
}
Η ψευδωνυμοποίηση είναι περιστασιακά χρήσιμη - είναι ο τρόπος με τον οποίο η chomp(@lines) τροποποιεί κάθε στοιχείο του πίνακα του καλούντος - αλλά σε καθημερινό κώδικα το ιδίωμα αποσυσκευασμένου-αντιγράφου είναι ο κανόνας.
wantarray και το περιβάλλον κλήσης#
Μια sub που θέλει να συμπεριφέρεται διαφορετικά ανάλογα με το αν κλήθηκε σε βαθμωτό, λίστα, ή κενό περιβάλλον εξετάζει τη wantarray:
sub items {
return wantarray ? (1, 2, 3) : 3;
}
my @list = items(); # (1, 2, 3)
my $cnt = items(); # 3
items(); # void - return value discarded
Η @_ και η wantarray είναι τα δύο κομμάτια της εικόνας σύμβασης κλήσης. Η @_ λέει τι μεταβιβάστηκε· η wantarray λέει τι αναμένεται πίσω.
@_ μετά από shift, pop, unshift, push#
Η τροποποίηση της ίδιας της @_ (όχι των στοιχείων της) δεν έχει αποτέλεσμα ψευδωνυμοποίησης στον καλούντα - είναι μια κανονική τοπική μεταβλητή πίνακα. Η shift @_ αφαιρεί το πρώτο όρισμα, αφήνοντας τα υπόλοιπα:
sub method_call {
my $self = shift; # standard OO pattern
my %args = @_; # rest of args as a hash
...
}
Η shift χωρίς ορίσματα μέσα σε υπορουτίνα χρησιμοποιεί εξ ορισμού τη @_, γι” αυτό βλέπετε my $self = shift; παντού.
$_ = shift - περιμένετε, τι;#
Ένα συνηθισμένο παραπλανητικό ιδίωμα:
sub trim {
$_ = shift; # - set caller's $_ - DO NOT DO THIS
s/^\s+//;
s/\s+$//;
return $_;
}
Αυτό το $_ = shift γράφει στην καθολική πακέτου $_, η οποία είναι το θέμα βρόχου του καλούντος αν ο καλών βρίσκεται μέσα σε for. Η λύση είναι η local, όπως παραπάνω:
sub trim {
local $_ = shift;
s/^\s+//;
s/\s+$//;
return $_;
}
Δείτε επίσης#
map,grep- οι πιο συνηθισμένοι καταναλωτές ψευδωνυμοποίησης$_.shift,pop- χρησιμοποιούν εξ ορισμού τη@_μέσα σε υπορουτίνα.wantarray- η σύντροφος της@_στην εικόνα σύμβασης κλήσης.local- ο ασφαλής τρόπος ρύθμισης της$_μέσα σε sub στην οποία ο καλών μπορεί να βρίσκεται σε επανάληψη.Σύνδεση regex - η
=~είναι αυτό που χρησιμοποιείτε όταν δεν θέλετε τη σιωπηρή$_ως στόχο.