Βαθμωτά#
Ένα βαθμωτό είναι η μοναδιαία τιμή της 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- επιβολή βαθμωτού περιβάλλοντος σε λίστα ή πίνακα.$_- το σιωπηρό βαθμωτό για πολλές ενσωματωμένες συναρτήσεις.