Βαθμωτά#

Ένα βαθμωτό είναι η μοναδιαία τιμή της Perl. Περιέχει ένα από τα εξής: έναν αριθμό (ακέραιο ή κινητής υποδιαστολής), μια συμβολοσειρά, μια αναφορά ή undef. Το sigil είναι $, σε κάθε θέση όπου η τιμή είναι ένα μεμονωμένο βαθμωτό - συμπεριλαμβανομένης της περίπτωσης που η τιμή είναι ένα στοιχείο πίνακα ή hash:

$x                # the scalar named x
$arr[0]           # the first element of @arr - also a scalar
$h{key}           # one value from %h - also a scalar

Ένα βαθμωτό δεν είναι στατικά τυποποιημένο. Η ίδια μεταβλητή μπορεί να περιέχει έναν αριθμό τώρα και μια συμβολοσειρά λίγο αργότερα. Η Perl μετατρέπει μεταξύ των δύο κάθε φορά που ένας τελεστής απαιτεί τη μία μορφή ή την άλλη· δείτε numbers and strings.

Αλήθεια, ορισμένη τιμή και undef#

Δύο σχετικές αλλά διακριτές ερωτήσεις για ένα βαθμωτό:

defined $x        # is there any value at all?
$x ? T : F        # is the value true?

Ένα βαθμωτό είναι ψευδές σε λογικό περιβάλλον αν είναι ένα από τα εξής:

undef             # the undefined value
0                 # numeric zero
0.0               # also numeric zero
""                # empty string
"0"               # the literal string "0"

Όλα τα υπόλοιπα είναι αληθή. Σημειώστε ότι τα "00", "0.0", "0 but true" και "0E0" είναι όλα αληθή - είναι μη κενές συμβολοσειρές που δεν ταιριάζουν με το κυριολεκτικό "0". Τα τελευταία δύο είναι κοινά ιδιώματα για «αυτή η συνάρτηση επέστρεψε επιτυχώς αλλά δεν υπήρχε τίποτα να μετρηθεί»:

sub touch_files {
    my $count = 0;
    $count++ for grep { -e $_ && utime undef, undef, $_ } @_;
    return $count || '0E0';     # true even on zero work, so callers
                                # can write `if (touch_files(...))`
}

Η defined είναι ο μόνος τρόπος να διακρίνετε την undef από τις ψευδείς-αλλά-ορισμένες τιμές. Ένα συνηθισμένο σφάλμα:

if ($cache{$key}) { ... }            # WRONG - false for empty/0/undef
if (exists $cache{$key}) { ... }      # right - pure presence test
if (defined $cache{$key}) { ... }     # right - value-not-undef test

Χρησιμοποιήστε την defined όταν το μόνο που σας ενδιαφέρει είναι «υπάρχει εδώ τιμή;»· την exists για «υπάρχει αυτό το κλειδί/δείκτης στον περιέκτη;» (οι δύο διαφέρουν σε αραιούς πίνακες και σε κλειδιά που έχουν υποστεί delete).

Δυναμική τυποποίηση#

Ένα βαθμωτό μπορεί να αλλάξει μορφή κατά την εκτέλεση:

my $x = 42;          # internally an integer
$x = "hello";        # now a string
$x = 3.14;           # now a float
$x = \@items;        # now a reference

Ο περισσότερος κώδικας δεν χρειάζεται ποτέ να σκεφτεί ποια εσωτερική μορφή έχει αυτή τη στιγμή ένα βαθμωτό. Οι εξαιρέσεις είναι βιβλιοθήκες σειριοποίησης JSON που ενδιαφέρονται αν το 1 ανατέθηκε ως αριθμός ή ως συμβολοσειρά, και οι βοηθοί ενδοσκόπησης του Scalar::Util (looks_like_number, dualvar).

«Μοιάζει με αριθμό»#

Όταν η Perl μετατρέπει μια συμβολοσειρά σε αριθμό, σταματάει στον πρώτο χαρακτήρα που δεν ανήκει σε ένα έγκυρο αριθμητικό πρόθεμα:

"42"        + 1   # 43
"42abc"     + 1   # 43      - leading digits parsed
"abc42"     + 1   # 1       - no leading digits, treated as 0
" 42"       + 1   # 43      - leading whitespace allowed
"4_2"       + 1   # 5       - underscores in literals only, NOT in strings
"0x1F"      + 1   # 1       - hex string is NOT auto-recognised; hex() does

Η ασυμφωνία μεταξύ αριθμητικών κυριολεκτικών (που αναγνωρίζουν _ και 0x) και αριθμητικών συμβολοσειρών (που δεν το κάνουν) είναι μία από τις συχνότερα αναφερόμενες ερωτήσεις «γιατί» στην Perl. Χρησιμοποιήστε hex / oct όταν η είσοδος είναι συμβολοσειρά σε μη δεκαδική μορφή:

my $bytes = hex "1F";        # 31
my $perms = oct "0755";       # 493
my $perms = oct "0o755";      # 493 - explicit octal prefix
my $bytes = oct "0x1F";       # 31  - oct() accepts any prefix

Με use warnings, μια αριθμητική πράξη σε μη αριθμητική συμβολοσειρά εκπέμπει Argument «…» isn’t numeric in addition (+). Η πράξη επιστρέφει 0 - η προειδοποίηση, όχι ένα μοιραίο σφάλμα, είναι το σήμα.

Διπλές τιμές#

Ορισμένα βαθμωτά φέρουν ταυτόχρονα μορφή συμβολοσειράς και αριθμού, με επιλογή ανάλογα με το περιβάλλον. Το κλασικό παράδειγμα είναι η $!:

$!                # in string context: "Permission denied"
$! + 0            # in numeric context: 13

Μπορείτε να φτιάξετε τη δική σας με Scalar::Util::dualvar:

use Scalar::Util qw(dualvar);
my $err = dualvar 13, 'Permission denied';

print "err is $err";           # "err is Permission denied"
print "err is " . ($err + 0);  # "err is 13"

Τα βαθμωτά διπλής τιμής είναι ένα εξειδικευμένο εργαλείο. Η συνηθισμένη περίπτωση όπου έχουν σημασία είναι η $! (errno)· η γενική διέξοδος είναι ο βοηθός dualvar.

«0 but true»#

Η κυριολεκτική συμβολοσειρά "0 but true" είναι το κανονικό ιδίωμα της Perl για «μια συνάρτηση της οποίας η κανονική επιστροφή είναι ένα πλήθος, αλλά το πλήθος είναι μηδέν και η κλήση πέτυχε». Είναι αληθής (μη κενή, όχι "0") αλλά αριθμητικά ίση με 0:

my $hits = "0 but true";

if ($hits)        { print "succeeded\n"; }    # prints
print $hits + 0;                               # 0
print "got $hits results\n";                   # got 0 but true results

Ο μεταγλωττιστής αναγνωρίζει επίσης ειδικά την "0 but true" και παραλείπει την προειδοποίηση isn’t numeric που θα εξέπεμπε οποιαδήποτε άλλη συμβολοσειρά «0 ακολουθούμενο από σκουπίδια».

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

  • Numbers and strings - πώς οι μορφές ακεραίου, κινητής υποδιαστολής και συμβολοσειράς μετατρέπονται μεταξύ τους και πού βρίσκονται οι γωνιακές περιπτώσεις.

  • References - η \X παράγει ένα βαθμωτό που δείχνει σε μια άλλη τιμή.

  • Context - πότε ένα βαθμωτό παίρνει μία τιμή έναντι πολλών.

  • defined, undef - έλεγχος και παραγωγή της απροσδιόριστης τιμής.

  • scalar - επιβολή βαθμωτού περιβάλλοντος σε λίστα ή πίνακα.

  • $_ - το σιωπηρό βαθμωτό για πολλές ενσωματωμένες συναρτήσεις.