Κλάσεις και αντικειμενοστρέφεια
bless#
Σημαδεύει αυτό στο οποίο δείχνει μια αναφορά ως αντικείμενο σε ένα πακέτο.
Η bless συνδέει τον αναφερόμενο της REF με το πακέτο που κατονομάζει το CLASSNAME, ώστε οι κλήσεις μεθόδων μέσω της REF να αποστέλλονται στις υπορουτίνες αυτού του πακέτου (και στους προγόνους του στο @ISA). Η ίδια η αναφορά δεν αλλάζει· αυτό που αλλάζει είναι η ετικέτα κλάσης του αναφερόμενου. Η bless επιστρέφει την REF, γι” αυτό είναι σχεδόν πάντα η τελευταία εντολή σε έναν κατασκευαστή.
Σύνοψη#
bless REF, CLASSNAME
bless REF
Τι επιστρέφεται#
Την ίδια αναφορά που πέρασε ως πρώτο όρισμα, η οποία τώρα φέρει την ετικέτα κλάσης CLASSNAME. Η επιστροφή της αναφοράς σας επιτρέπει να καλέσετε την bless ως τελική κλήση από έναν κατασκευαστή:
sub new {
my ($class, %args) = @_;
return bless { %args }, $class;
}
Από εκείνο το σημείο και μετά, η ref επί της επιστρεφόμενης αναφοράς αποδίδει το όνομα κλάσης αντί για τον ακατέργαστο τύπο αναφοράς (HASH, ARRAY, CODE, …).
Μορφές#
Δύο μορφές κλήσης, η μία ισχυρά προτιμώμενη:
Δύο ορισμάτων - χρησιμοποιήστε πάντα αυτή.
bless $ref, $class;
Ο αναφερόμενος γίνεται αντικείμενο στο πακέτο που κατονομάζει η
$class. Η χρήση του πρώτου ορίσματος του κατασκευαστή ($_[0], συμβατικά$class) διατηρεί τον κατασκευαστή κληρονομήσιμο: μια υποκλάση που καλείParent::new('Child', ...)λαμβάνει πίσω ένα αντικείμενο blessed στοChild, όχι στοParent.Δύο ορισμάτων με κενή συμβολοσειρά - bless στο
main.bless $ref, "";
Ένα κενό
CLASSNAMEαντιμετωπίζεται ως το πακέτοmain. Σπάνια χρήσιμο εκτός από σκόπιμα τεχνάσματα.Ενός ορίσματος - αποθαρρύνεται.
bless $ref;
Ο αναφερόμενος γίνεται bless στο τρέχον πακέτο (το πακέτο στο οποίο μεταγλωττίζεται η κλήση
bless). Αυτό σπάει την κληρονομικότητα: μια υποκλάση που κληρονομεί έναν κατασκευαστήblessενός ορίσματος καταλήγει εξακολουθητικά με αντικείμενα στο πακέτο του γονέα, όχι του καλούντος. Χρησιμοποιήστε τη μορφή δύο ορισμάτων εκτός εάν έχετε συγκεκριμένο λόγο να μην το κάνετε, και τεκμηριώστε τον λόγο.
Παραδείγματα#
Μια ελάχιστη κλάση βασισμένη σε κατακερματισμό:
package Point;
sub new {
my ($class, $x, $y) = @_;
return bless { x => $x, y => $y }, $class;
}
sub x { $_[0]->{x} }
sub y { $_[0]->{y} }
package main;
my $p = Point->new(3, 4);
print ref $p, "\n"; # Point
print $p->x, ",", $p->y; # 3,4
Κληρονομήσιμος κατασκευαστής - η ίδια new λειτουργεί για υποκλάση χωρίς τροποποίηση:
package Shape;
sub new {
my ($class, %args) = @_;
return bless { %args }, $class;
}
package Circle;
our @ISA = ('Shape');
sub area {
my $self = shift;
return 3.14159 * $self->{radius} ** 2;
}
package main;
my $c = Circle->new(radius => 5);
print ref $c, "\n"; # Circle
print $c->area, "\n"; # 78.53975
Τα αντικείμενα βασισμένα σε πίνακα λειτουργούν με τον ίδιο τρόπο - οποιοσδήποτε τύπος αναφοράς μπορεί να γίνει bless:
package Pair;
sub new {
my ($class, $a, $b) = @_;
return bless [$a, $b], $class;
}
sub first { $_[0]->[0] }
sub second { $_[0]->[1] }
my $p = Pair->new("left", "right");
print $p->first, "/", $p->second; # left/right
Η εκ νέου bless ενός υπάρχοντος αντικειμένου αλλάζει την ετικέτα κλάσης του επιτόπου:
my $obj = bless {}, 'OldClass';
bless $obj, 'NewClass';
print ref $obj; # NewClass
Η bless επιστρέφει την αναφορά, γι” αυτό λειτουργεί η αλυσίδωση σε κλήσεις μεθόδων στην ίδια γραμμή:
Logger->new(file => $path)->info("started");
# ^ called on the blessed ref
Οριακές περιπτώσεις#
Αυτό που λαμβάνει την ετικέτα είναι η αναφορά, όχι η μεταβλητή. Τα αντίγραφα της αναφοράς μοιράζονται την ετικέτα κλάσης επειδή όλα δείχνουν στον ίδιο αναφερόμενο:
my $a = bless {}, 'Foo'; my $b = $a; print ref $b; # Foo
Η εκ νέου bless επιτρέπεται και είναι άμεση. Μια αναφορά μπορεί να γίνει bless όσες φορές θέλετε· κάθε κλήση γράφει πάνω από την προηγούμενη ετικέτα κλάσης. Δεν υπάρχει ενσωματωμένη «unbless» - κάντε rebless σε ένα ουδέτερο πακέτο αν χρειάζεται να αφαιρέσετε την αντικειμενική φύση από έναν αναφερόμενο στον οποίο εξακολουθείτε να διατηρείτε αναφορές.
CLASSNAMEίσο με""σημαίνειmain. Ρητό και σπάνια επιθυμητό· συνήθως ένδειξη ότι ένα υπολογισμένο όνομα κλάσης βγήκε κενό κατά λάθος.Αποφύγετε το
bless $ref, "0". Το όνομα κλάσης"0"είναι ψευδής τιμή, οπότε κώδικας που ελέγχειif (ref $obj) { ... }θα διαβάσει εσφαλμένα το αντικείμενο ως «μη αναφορά». Επιλέξτε οποιοδήποτε όνομα κλάσης που δεν είναι ψευδές.Σύμβαση πεζών-κεφαλαίων για ονόματα κλάσεων. Χρησιμοποιήστε ανάμεικτη γραφή (
My::Package). Τα ονόματα με ΟΛΟΚΕΦΑΛΑΙΑ είναι δεσμευμένα για ενσωματωμένους τύπους της Perl (SCALAR,ARRAY,HASH,CODE, …) και τα ονόματα μόνο με πεζά είναι δεσμευμένα για pragmas (strict,warnings,utf8). Το bless σε οποιονδήποτε από αυτούς τους χώρους ονομάτων προκαλεί σύγχυση με τον μηχανισμό σε επίπεδο γλώσσας.Πρώτο όρισμα που δεν είναι αναφορά αποτελεί μοιραίο σφάλμα. Το
bless 42, 'Foo'πεθαίνει μεCan't bless non-reference value. Το πρώτο όρισμα πρέπει να είναι αναφορά.Η
blessενός ορίσματος επιλέγει το πακέτο μεταγλώττισης. Χρησιμοποιεί το πακέτο μέσα στο οποίο βρίσκεται λεξιλογικά η κλήσηbless- όχι το πακέτο του καλούντος, όχι το πακέτο της$class. Αυτός ακριβώς είναι ο λόγος που σπάει την κληρονομικότητα και που υπάρχει η μορφή δύο ορισμάτων.Οι ασθενείς αναφορές και το bless αλληλεπιδρούν όπως αναμένεται. Η
Scalar::Util::weakenσε μια blessed αναφορά δεν την αποκαθιστά· η εξασθενημένη θυρίδα εξακολουθεί να βλέπει την ετικέτα κλάσης, και ηrefλειτουργεί μέχρι να καταστραφεί ο αναφερόμενος.Η
DESTROYεκπυρσοκροτεί στον blessed αναφερόμενο. Όταν η τελευταία αναφορά σε έναν blessed αναφερόμενο εξαφανιστεί, η Perl καλεί τηνDESTROYστην κλάση της αναφοράς (ακολουθώντας το@ISA). Η αλλαγή της κλάσης με μια καθυστερημένηblessαλλάζει ποιαDESTROYεκτελείται.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
ref- διαβάστε πίσω την ετικέτα κλάσης από μια blessed αναφορά, ή τον τύπο αναφοράς (HASH,ARRAY, …) για μια μη-blessedpackage- δηλώστε το πακέτο στο οποίο μεταγλωττίζεται μια κλήσηblessή ένας ορισμός υπορουτίνας· ο στόχος τηςblessενός ορίσματοςclass- η πειραματική ενσωματωμένη σύνταξη κλάσης που αντικαθιστά το χειρωνακτικά γραμμένο μοτίβο κατασκευαστήpackage+blessμε δηλωτική σύνταξηtie- μια διαφορετική μορφή μαγείας ανά μεταβλητή· άσχετη με τηνblessπαρά την επιφανειακή διατύπωση «επισύναψη συμπεριφοράς σε μια τιμή»@ISA- η αλυσίδα κληρονομικότητας που συμβουλεύεται κατά την αποστολή μιας κλήσης μεθόδου σε blessed αναφοράDESTROY- η μέθοδος καταστροφέα που η Perl καλεί στον blessed αναφερόμενο όταν εξαφανιστεί η τελευταία του αναφορά· δηλώνεται ως υπορουτίνα μέσα στο πακέτο της κλάσης