Ροή ελέγχου · Κλάσεις και αντικειμενοστρέφεια
method#
Δηλώνει μια ονομασμένη μέθοδο στιγμιότυπου μέσα σε ένα μπλοκ class.
Η method ορίζει υπορουτίνα που αναμένει να κληθεί σε αντικείμενο της περικλείουσας κλάσης. Συμπεριφέρεται σαν sub, με δύο πρόσθετες εγγυήσεις που η sub δεν σας δίνει: το λεξιλογικό $self δένεται αυτόματα στον επικαλούμενο, και οι υπογραφές είναι πάντα ενεργές - γράφετε τις παραμέτρους σαν να ίσχυε use feature 'signatures', και το $self δεν εμφανίζεται σε αυτή την υπογραφή.
Η method είναι έγκυρη μόνο μέσα σε δήλωση class. Εκτός μπλοκ κλάσης αποτελεί σφάλμα κατά τη μεταγλώττιση.
Σημείωση
Πειραματικό χαρακτηριστικό Οι δεσμευμένες λέξεις class, method και field είναι μέρος του πειραματικού χαρακτηριστικού class (εισάχθηκε στην Perl 5.38). Η ενεργοποίησή του με use feature 'class'; εκπέμπει προειδοποίηση στην κατηγορία experimental::class. Η σύνταξη και σημασιολογία ενδέχεται ακόμη να αλλάξουν μεταξύ εκδόσεων της Perl.
Σύνοψη#
method NAME BLOCK
method NAME SIGNATURE BLOCK
method NAME : ATTRS BLOCK
method SIGNATURE BLOCK # anonymous
method BLOCK # anonymous
Τι επιστρέφεται#
Η method είναι δήλωση, όχι έκφραση, στην ονομασμένη μορφή της - εγκαθιστά τη μέθοδο στον πίνακα μεθόδων της περικλείουσας κλάσης και αποτιμάται σε τίποτα χρήσιμο στη θέση εντολής. Η ανώνυμη μορφή επιστρέφει αναφορά κώδικα που θυμάται το περιβάλλον κλάσης και μπορεί να κληθεί αργότερα με επικαλούμενο αντικειμένου.
Το σώμα μιας method καλείται με το αντικείμενο ως επικαλούμενο. Η τιμή επιστροφής της μεθόδου είναι ό,τι επιστρέφει το μπλοκ, ακολουθώντας τους ίδιους κανόνες περιβάλλοντος με μια κανονική κλήση υπορουτίνας.
Τι σας δίνει η method που δεν σας δίνει η sub#
Τέσσερα πράγματα διαφέρουν από τη γραφή sub μέσα σε μπλοκ class:
Το
$selfείναι προδηλωμένο. Ένα λεξιλογικό$selfδημιουργείται στην εμβέλεια της μεθόδου και αρχικοποιείται στον επικαλούμενο. Δεν - και δεν θα έπρεπε να - το αφαιρείτε με shift από το@_.Οι υπογραφές είναι πάντα ενεργές. Μπορείτε να γράψετε
method greet($name) { ... }χωρίςuse feature 'signatures'. Ο επικαλούμενος$selfκαταναλώνεται πριν δέσει η υπογραφή, οπότε δεν εμφανίζεται ποτέ στη λίστα παραμέτρων.Τα πεδία είναι σε εμβέλεια. Όλες οι μεταβλητές
fieldπου δηλώνονται στην περικλείουσα κλάση είναι ορατές με τα λεξιλογικά τους ονόματα μέσα στο σώμα της μεθόδου. Μια απλήsubμέσα σε μπλοκclassδεν βλέπει πεδία.Καταχωρείται ως μέθοδος. Ο πίνακας μεθόδων της κλάσης καταγράφει το όνομα, το οποίο αναζητά ο μηχανισμός επίλυσης μεθόδων για αποστολή
$obj->name(...). Μια απλήsubμέσα στο μπλοκ κλάσης είναι βοηθός, όχι μέθοδος.
Με άλλα λόγια: μια sub μέσα σε μπλοκ class είναι συνηθισμένη υπορουτίνα πακέτου που τυχαίνει να ζει στον χώρο ονομάτων εκείνου του πακέτου. Δεν έχει $self, δεν έχει ορατότητα πεδίων, και δεν αποτελεί μέρος της διεπαφής μεθόδων της κλάσης - καλέστε την μέσω ClassName::helper(...) αν το χρειάζεστε, όχι μέσω βέλους.
Παραδείγματα#
Μια ελάχιστη κλάση με μέθοδο και πεδίο:
use v5.38;
use feature 'class';
no warnings 'experimental::class';
class Greeter {
field $greeting = "Hello";
method greet($name) {
return "$greeting, $name";
}
}
my $g = Greeter->new;
say $g->greet("world"); # Hello, world
Οι προεπιλεγμένες τιμές υπογραφής λειτουργούν ακριβώς όπως για την sub:
class Greeter {
field $greeting = "Hello";
method greet($name = "someone") {
return "$greeting, $name";
}
}
say Greeter->new->greet; # Hello, someone
Μια μέθοδος χωρίς παραμέτρους εξακολουθεί να χρησιμοποιεί τη μορφή υπογραφής - οι κενές () δεν είναι απαιτητές, αλλά επιτρέπονται και αποτελούν το σύνηθες στιλ όταν η μέθοδος δέχεται ορίσματα αλλού στην κλάση:
class Counter {
field $n = 0;
method inc { $n++ }
method value () { return $n }
}
Μια ανώνυμη μέθοδος - χρήσιμη ως εργοστάσιο ή ως callback που χρειάζεται πρόσβαση στο $self και στα πεδία:
class AnonMethodFactory {
method make_printer {
return method { say "called on $self" };
}
}
Μια λεξιλογική (ιδιωτική) μέθοδος δηλωμένη με my method. Επικαλεστείτε την μέσω του τελεστή ->&, που παρακάμπτει την αναζήτηση μεθόδου και καλεί τη λεξιλογική απευθείας σαν να ήταν μέθοδος:
class LexicalMethod {
my method _check ($x, $y) {
return $x > 0 && $y > 0;
}
method process ($x, $y) {
return unless $self->&_check($x, $y);
# ...
}
}
Κανονική sub μέσα σε κλάση, σε αντιδιαστολή με method - η sub είναι βοηθός, η method είναι η δημόσια διεπαφή:
class Temperature {
field $celsius;
sub _c_to_f ($c) { $c * 9 / 5 + 32 } # helper, no $self, no fields
method fahrenheit {
return _c_to_f($celsius);
}
}
Οριακές περιπτώσεις#
Εκτός μπλοκ
classείναι σφάλμα κατά τη μεταγλώττιση. Τοmethod foo { ... }στο ανώτατο επίπεδο, ή μέσα σεpackageπου δεν είναιclass, δεν αναλύεται. Χρησιμοποιήστε εκεί τηνsub.Το
$selfείναι μόνο για ανάγνωση με την έννοια ότι δεν μπορείτε να δηλώσετε άλλο λεξιλογικό με το ίδιο όνομα στην αρχή της μεθόδου - βρίσκεται ήδη σε εμβέλεια. Η εκχώρηση στο$self(π.χ.$self = ...) επιτρέπεται αλλά σπάνια είναι χρήσιμη και δεν αλλάζει τον επικαλούμενο του καλούντος.Το
@_δεν είναι η λίστα ορισμάτων που περιμένετε. Υπό τις υπογραφές που ενεργοποιεί ηmethod, το@_μέσα στο σώμα είναι κενό μετά τη δέσμευση της υπογραφής, όπως ακριβώς σε κάθε sub που χρησιμοποιεί υπογραφή. Διαβάστε τις παραμέτρους από την υπογραφή, όχι από το@_.Η σειρά επίλυσης μεθόδου ορίζεται από την περικλείουσα κλάση. Η ίδια η
methodδεν δέχεται επιλογή MRO· η κληρονομικότητα και η αποστολή ακολουθούν ό,τι διαμόρφωσε η δήλωσηclassμέσω:isaκαι συναφών γνωρισμάτων.Η
methodδεν συμμετέχει σε πρωτότυπα. Οι μέθοδοι επικαλούνται μέσω αποστολής, όχι με άμεσες κλήσεις πίνακα συμβόλων, οπότε τα πρωτότυπα (το γνώρισμα:prototype(...)σε μιαsub) δεν έχουν εδώ αποτέλεσμα. Χρησιμοποιήστε την υπογραφή για να περιορίσετε το σχήμα κλήσης.Γνωρίσματα. Η μορφή
method NAME : ATTRS BLOCKδέχεται γνωρίσματα με τον ίδιο τρόπο όπως ηsub NAME : ATTRS BLOCK. Το σύνολο των χρήσιμων γνωρισμάτων στις μεθόδους ακόμη σταθεροποιείται με το χαρακτηριστικόclass· συμβουλευτείτε το upstream πριν βασιστείτε σε προσαρμοσμένα.Παγίδα επιστροφής από μέθοδο με ανώνυμη μέθοδο. Το
return method { ... }επιστρέφει αναφορά κώδικα. Τοmethod { ... }ως τελευταία έκφραση μεθόδου χωρίςreturnεξακολουθεί να είναι αναφορά κώδικα, αλλά οι αναγνώστες συχνά την παρερμηνεύουν ως μπλοκ - προτιμήστε ρητήreturnγια σαφήνεια.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Το χαρακτηριστικό class - και επομένως η method - σημειώνεται πειραματικό στο upstream· η pperl κληρονομεί αυτή την κατάσταση και την κατηγορία προειδοποίησης experimental::class.
Δείτε επίσης#
class- δηλώνει το πακέτο μέσα στο οποίο ζει ηmethod· ηmethodαναλύεται μόνο μέσα σε μπλοκclassfield- ανά στιγμιότυπο μεταβλητές που είναι ορατές με το όνομά τους μέσα σε κάθεmethodτης περικλείουσας κλάσηςsub- δηλώστε κανονική υπορουτίνα· χρησιμοποιήστε αυτό για βοηθούς μέσα σε κλάση που δεν χρειάζονται$selfή πρόσβαση σε πεδία__CLASS__- το όνομα της τρέχουσας κλάσης, χρήσιμο μέσα σε μεθόδους που χρειάζεται να αποστείλουν πίσω σε κώδικα επιπέδου κλάσηςreturn- ρητή επιστροφή από σώμα μεθόδου· συνιστάται όταν η τελευταία έκφραση είναι η ίδια ανώνυμη μορφήmethod { ... }my- προθέστεmyσε μιαmethodγια να δηλώσετε λεξιλογική (ιδιωτική) μέθοδο που επικαλείται μέσω->&