Τελεστές ανάθεσης#

Απλή ανάθεση επιπλέον οι σύνθετες μορφές - κάθε δυαδικός τελεστής που παράγει τιμή έχει επίσης μια σύνθετη μορφή ανάθεσης που εφαρμόζει την πράξη επιτόπου.

Απλό =#

my $x = 10;                          # scalar assignment
my @a = (1, 2, 3);                   # list assignment
my ($x, $y, $z) = (1, 2, 3);         # destructuring
my ($first, @rest) = @items;         # one + remainder
my %h = (a => 1, b => 2);            # hash from key-value list

Η ανάθεση είναι δεξιά-προσεταιριστική - οι αλυσίδες αποτιμούνται από δεξιά προς αριστερά:

$a = $b = $c = 0;                    # parses as $a = ($b = ($c = 0))
                                     # all three become 0

Ολόκληρη η έκφραση ανάθεσης έχει τιμή: σε βαθμωτό περιβάλλον είναι η τιμή που ανατέθηκε· σε περιβάλλον λίστας είναι η λίστα στοιχείων στα οποία ανατέθηκε, σε σειρά από αριστερά προς δεξιά:

my $count = (my @items = qw(a b c)); # $count = 3
                                     # - number of elements assigned
                                     # to @items, in scalar context

while ((my $line = <$fh>) ne '') { ... }   # uses the assignment as
                                            # both side-effect and value

Ανάθεση λίστας σε βαθμωτό περιβάλλον#

Πιθανώς το πιο χρησιμοποιούμενο ιδίωμα Perl για το οποίο κανείς δεν μπορεί να αναφέρει τον κανόνα:

my $n = () = $string =~ /\d/g;       # count digits in $string

Αποκωδικοποιημένο:

  1. Η $string =~ /\d/g σε περιβάλλον λίστας δίνει όλες τις συλλήψεις ψηφίων.

  2. Η () = ... είναι ανάθεση λίστας στην κενή λίστα (δεν αναθέτει τίποτα, αλλά αποτιμά τη δεξιά πλευρά σε περιβάλλον λίστας).

  3. Η $n = (...) βάζει την ανάθεση λίστας σε βαθμωτό περιβάλλον, που αποτιμάται στον αριθμό στοιχείων στα δεξιά.

Αποτέλεσμα: η $n είναι το πλήθος αντιστοιχιών. Δεν υπάρχει scalar(grep ...) ή ενσωματωμένη count γι” αυτό· το τέχνασμα κενής λίστας είναι το κανονικό ιδίωμα.

Σύνθετη ανάθεση#

Κάθε δυαδικός τελεστής που ταιριάζει στο μοτίβο OP= υπάρχει. Η μηχανική είναι πανομοιότυπη με $x = $x OP $y, εκτός του ότι η $x αποτιμάται μόνο μία φορά στα αριστερά - κάτι που έχει σημασία όταν το lvalue έχει παρενέργεια (π.χ. αυτο-δημιουργία, κλήση συνάρτησης):

$h->{counter}++;                     # autoviv $h->{counter}, increment
$h->{counter} += 1;                  # same effect, but spell out the OP

Τελεστής

Ισοδύναμο

Χρήση

+=

$x = $x + $y

συσσώρευση

-=

$x = $x - $y

αφαίρεση επιτόπου

*=

$x = $x * $y

κλιμάκωση

/=

$x = $x / $y

διαίρεση επιτόπου

%=

$x = $x % $y

υπόλοιπο

**=

$x = $x ** $y

ύψωση σε δύναμη επιτόπου

.=

$x = $x . $y

προσθήκη (συμβολοσειρά)

x=

$x = $x x $y

επανάληψη (συμβολοσειρά), ή (@) x= n

&=

$x = $x & $y

bitmask AND-ίσον

|=

$x = $x | $y

bitmask OR-ίσον (ενεργοποίηση bits)

^=

$x = $x ^ $y

bitmask XOR-ίσον (εναλλαγή)

<<=

$x = $x << $y

αριστερή ολίσθηση επιτόπου

>>=

$x = $x >> $y

δεξιά ολίσθηση επιτόπου

&&=

$x = $x && $y

«στένεψε αν αληθές τώρα»

||=

$x = $x || $y

προεπιλογή αν ψευδές τώρα

//=

$x = $x // $y

προεπιλογή αν undef τώρα

$count    += 5;                      # arithmetic
$path     .= "/user";                # string append
$flags    |= FLAG_VERBOSE;           # set a flag bit
$flags    &= ~FLAG_VERBOSE;          # clear a flag bit
$cache    ||= load_data();           # lazy populate
$cfg{key} //= $default;              # default that respects 0 and ""
$str       x= 3;                     # repeat in place

Lvalues - τι μπορεί να εμφανιστεί στα αριστερά#

Ο αριστερός τελεστέος της = (ή οποιασδήποτε σύνθετης μορφής) πρέπει να είναι lvalue - μια θέση στην οποία μπορεί να γίνει εγγραφή. Τα lvalues της Perl περιλαμβάνουν:

  • Μια απλή βαθμωτή μεταβλητή: $x, $obj->{field}.

  • Μια μεταβλητή πίνακα ή hash: @arr, %h.

  • Ένα στοιχείο πίνακα ή τομή: $arr[3], @arr[1..3].

  • Ένα στοιχείο hash ή τομή: $h{key}, @h{qw(a b c)}.

  • Ένας αποαναφερόμενος περιέκτης: $$ref, @$aref, %{$h}.

  • Η μορφή δηλωμένη με local/my οποιουδήποτε από τα παραπάνω.

  • Μια υποσυμβολοσειρά: substr($s, $offset, $len) = "...".

  • Ένας τριαδικός του οποίου οι κλάδοι είναι lvalues (δείτε ternary).

  • Οι ψευδο-τελεστές pos, vec, keys σε tied hashes, ορισμένες θέσεις @_ και μια χούφτα εξειδικευμένων μορφών.

Τις περισσότερες φορές γράφετε ένα lvalue χωρίς να το σκεφτείτε. Οι περιπτώσεις που σταματάτε και ελέγχετε είναι εξωτικές - substr ως lvalue, τριαδικός ως lvalue, τομή πίνακα ως στόχος ανάθεσης λίστας.

Ανάθεση λίστας σε πολλαπλούς στόχους#

Η δεξιά πλευρά αποτιμάται πρώτα σε περιβάλλον λίστας, στη συνέχεια κατανέμεται στα lvalues στα αριστερά. Αυτό κάνει την ανταλλαγή εύκολη:

($a, $b) = ($b, $a);                 # swap
($x, $y, $z) = ($y, $z, $x);         # rotate left

Αν οι λίστες διαφέρουν σε μήκος:

  • Περισσότερες τιμές στα δεξιά από θέσεις στα αριστερά → τα περισσευούμενα απορρίπτονται σιωπηλά.

  • Περισσότερες θέσεις στα αριστερά από τιμές στα δεξιά → οι ασυμπλήρωτες θέσεις γίνονται undef.

my ($a, $b) = (1, 2, 3, 4);          # $a=1, $b=2; 3 and 4 dropped
my ($a, $b, $c) = (1, 2);            # $a=1, $b=2, $c=undef

Ένας τελικός πίνακας ή hash στα αριστερά απορροφά τα υπόλοιπα:

my ($head, @tail) = @items;          # $head = first element
                                     # @tail = the rest
my ($head, %tail) = @items;          # if @items has key/value pairs
                                     # after the first

Μόνο ένας πίνακας ή hash στην αριστερή πλευρά· αλλιώς δεν θα ήταν σαφές πού τελειώνει ο ένας και πού αρχίζει ο επόμενος.

Προτεραιότητα#

Οι τελεστές ανάθεσης βρίσκονται στη γραμμή 19 - αρκετά χαμηλά, χαλαρότεροι από σύγκριση και ?:, σφιχτότεροι μόνο από τους τελεστές κόμματος και τους λογικούς σε μορφή λέξης (and, or, not, xor). Γι” αυτό η my $fh = open ... or die λειτουργεί (ο or είναι ακόμα πιο χαλαρός από το =).

Δείτε επίσης#

  • Logical - οι ||=, //=, &&= είναι τα workhorses των ιδιωμάτων «προεπιλογή αν λείπει».

  • Subscript - οι περισσότερες μορφές lvalue περιλαμβάνουν subscript.

  • Comma - η = αναλύεται ξεχωριστά από τη γύρω λίστα , μέσω προτεραιότητας· η κατανόηση γραμμής 19 έναντι 20 είναι αυτό που σας λέει πότε η (a, b)=(c, d) κατανέμεται έναντι να είναι μία ενιαία λίστα.