Εμβέλεια · Αρθρώματα

import#

Συμπλήρωση του χώρου ονομάτων του καλούντος με ονόματα που επιλέγει να εξάγει ένα άρθρωμα.

Η import δεν είναι ενσωματωμένη συνάρτηση. Είναι μέθοδος κλάσης που ορίζει ένα άρθρωμα ώστε η use να έχει κάπου να παραδώσει τη λίστα ορισμάτων. Όταν γράφετε use Module LIST, η Perl φορτώνει το άρθρωμα και έπειτα καλεί Module->import(LIST) κατά τη μεταγλώττιση, στο πακέτο που περιέχει τη δήλωση use. Ό,τι κάνει αυτή η μέθοδος - εγκατάσταση υπορουτινών στο stash του καλούντος, αναστροφή bits χαρακτηριστικών, ορισμός σημαιών pragma - είναι ολόκληρο το συμβόλαιο import του αρθρώματος.

Τα περισσότερα αρθρώματα δεν γράφουν ποτέ import χειροκίνητα· την κληρονομούν από τον Exporter και δηλώνουν αντί αυτού @EXPORT / @EXPORT_OK. Τα pragmas (strict, warnings, feature) γράφουν τη δική τους import επειδή ό,τι εγκαθιστούν είναι λεξιλογική κατάσταση, όχι υπορουτίνες.

Σύνοψη#

Module->import;
Module->import(LIST);
Module->import(@symbols);

Μέσα σε ένα άρθρωμα, ο ορισμός μοιάζει με:

package My::Module;
sub import {
    my ($class, @args) = @_;
    # install names into caller's package
}

Τι επιστρέφεται#

Η τιμή επιστροφής της import απορρίπτεται από τη use. Ένα άρθρωμα που καλείται άμεσα ως μέθοδος κληρονομεί όποια σύμβαση επέλεξε ο συντάκτης - κατά σύμβαση, μην επιστρέφετε τίποτα χρήσιμο.

Το ορατό αποτέλεσμα είναι στο πακέτο του καλούντος: μετά την επιστροφή της use Module qw(foo bar), οι foo και bar είναι καλέσιμες χωρίς πρόθεμα πακέτου από τον κώδικα που εκτέλεσε την use.

Πώς η use καλεί την import#

Η use Module LIST ισοδυναμεί, ουσιαστικά, με:

BEGIN {
    require Module;
    Module->import(LIST);
}

Τρεις συνέπειες προκύπτουν από αυτή την ισοδυναμία:

  • Χρόνος μεταγλώττισης. Η import τρέχει όσο το περικλείον αρχείο ακόμη αναλύεται. Τυχόν πρωτότυπα υπορουτίνας ή λεξιλογικά pragmas που εγκαθιστά είναι ορατά στο υπόλοιπο του αρχείου από εκείνο το σημείο και έπειτα. Οτιδήποτε γίνεται κατά τον χρόνο εκτέλεσης - άνοιγμα αρχείων, ανάγνωση ρυθμίσεων - συμβαίνει νωρίτερα από ό,τι υποδηλώνει μια αφελής ανάγνωση της πηγής.

  • Η caller αντικατοπτρίζει το μπλοκ BEGIN, όχι την περιβάλλουσα υπορουτίνα. Μια μέθοδος import που επιθεωρεί την caller(0) βλέπει το πακέτο που έγραψε use Module, που είναι ακριβώς αυτό που θέλει· δεν βλέπει την υπορουτίνα που περιέχει τη δήλωση use.

  • Απούσα λίστα έναντι κενής λίστας. Η use Module χωρίς λίστα καλεί Module->import χωρίς ορίσματα - το άρθρωμα εγκαθιστά τα προεπιλεγμένα του. Η use Module () με ρητή κενή λίστα παρακάμπτει εντελώς την κλήση import. Αυτό είναι το ιδίωμα για «φόρτωσε το αρχείο αλλά μην αγγίξεις τον χώρο ονομάτων μου».

Η no Module LIST είναι η κατοπτρική εικόνα: καλεί Module->unimport(LIST) αντί για import. Τα pragmas το χρησιμοποιούν για να απενεργοποιήσουν χαρακτηριστικά για την περικλείουσα λεξιλογική εμβέλεια.

Ορισμός μιας μεθόδου import#

Η κοινή διαδρομή είναι η κληρονομικότητα από τον Exporter:

package My::Utils;
use Exporter 'import';                 # installs Exporter::import
our @EXPORT_OK = qw(slurp trim);
sub slurp { ... }
sub trim  { ... }
1;

Οι καλούντες έπειτα γράφουν:

use My::Utils qw(slurp trim);
slurp($path);

Μια χειρόγραφη import έχει την ίδια μορφή με κάθε μέθοδο - λαμβάνει το όνομα κλάσης ως πρώτο όρισμα και τη λίστα ορισμάτων της use ως τα υπόλοιπα:

package My::Feature;
sub import {
    my ($class, @flags) = @_;
    my $caller = caller;
    no strict 'refs';
    for my $name (@flags) {
        *{ "${caller}::${name}" } = \&{ "${class}::${name}" };
    }
}

Το όνομα πακέτου του καλούντος προέρχεται από την caller, όχι από το $class - το $class είναι όποιο άρθρωμα ονομάτισε ο χρήστης στη γραμμή use.

Παραδείγματα#

Προεπιλεγμένη εισαγωγή - ό,τι περιέχει η λίστα @EXPORT του αρθρώματος:

use List::Util;                        # imports nothing by default
use File::Basename;                    # imports basename, dirname, ...

Ρητή λίστα εισαγωγής - μόνο τα ονόματα που ζητάτε:

use List::Util qw(sum min max);
my $total = sum(1, 2, 3);              # 6

Κενή λίστα - φορτώστε το αρχείο, μην αγγίξετε τίποτα:

use POSIX ();                          # no POSIX::* names imported
my $pi = POSIX::acos(-1);              # fully qualified call

Εισαγωγή από pragma - λεξιλογικό αποτέλεσμα στο περικλείον μπλοκ:

use strict;
use warnings;
{
    no warnings 'uninitialized';       # unimport in this block only
    print "x=", $x, "\n";
}

Άμεση κλήση της import μετά από require κατά τον χρόνο εκτέλεσης:

require My::Plugin;
My::Plugin->import(@config);           # deferred to runtime on purpose

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

Οριακές περιπτώσεις#

  • Δεν υπάρχει ενσωματωμένη import. Η print import(@list) καλεί την υπορουτίνα ονόματι import στο τρέχον πακέτο (αν υπάρχει)· δεν είναι τελεστής σε επίπεδο γλώσσας. Οι κανόνες ανάλυσης ισχύουν όπως για οποιαδήποτε υπορουτίνα ορισμένη από τον χρήστη.

  • Παράλειψη λίστας έναντι κενής λίστας είναι η πιο κοινή πηγή σύγχυσης. Η use Mod καλεί την import· η use Mod () όχι. Το () δεν είναι στιλιστικό κενό - είναι σήμα.

  • Το όρισμα έκδοσης εκτελεί την VERSION, όχι την import. Η use Mod 1.23 LIST καλεί Mod->VERSION(1.23) πριν την Mod->import(LIST). Μια σκέτη use Mod 1.23 εξακολουθεί να είναι έλεγχος έκδοσης ακολουθούμενος από προεπιλεγμένη import. Για έλεγχο έκδοσης χωρίς εισαγωγές, γράψτε use Mod 1.23 ().

  • Καθόλου ορισμένη import. Αν το άρθρωμα ούτε γράφει ούτε κληρονομεί import, η use Module LIST με μη κενή λίστα δεν παράγει σφάλμα - η κλήση μεθόδου περνά σιωπηρά καθώς η UNIVERSAL::can('import') επιστρέφει ψευδές και η use την αντιμετωπίζει ως «τίποτα να γίνει». Η μη κενή LIST τότε αγνοείται στην πράξη, κάτι που σχεδόν ποτέ δεν είναι ό,τι ήθελε ο καλών.

  • Η import τρέχει μία φορά ανά δήλωση use, όχι μία φορά ανά διεργασία. Η use Mod qw(foo); use Mod qw(bar); καλεί την import δύο φορές, παρότι το αρχείο φορτώνεται μόνο μία - οι @INC / %INC ελέγχουν τη φόρτωση του αρχείου, όχι την κλήση μεθόδου.

  • Η εγκατάσταση συμβόλων δεν είναι αυτόματη. Η γραφή μεθόδου import που απλώς επιστρέφει δεν κάνει τίποτα· πρέπει να εκχωρήσετε στο stash του καλούντος (*{"${caller}::name"} = \&sub) ή να αναθέσετε στον Exporter.

  • Τα pragmas τυπικά εγκαθιστούν λεξιλογική κατάσταση, όχι υπορουτίνες σε επίπεδο πακέτου. Η import τους καλεί συναρτήσεις όπως warnings::import_into ή χειρίζεται την %^H· γι” αυτό το αποτέλεσμα ενός pragma έχει εμβέλεια το περικλείον μπλοκ αντί να διατηρείται στο πακέτο.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

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

  • use - ο φορτωτής κατά τη μεταγλώττιση που επικαλείται την import· η κατανόηση του ενός απαιτεί το άλλο

  • no - ο κάτοπτρος της use· καλεί την unimport με τους ίδιους κανόνες πέρασης ορισμάτων

  • require - φορτώνει το αρχείο χωρίς να καλεί import· συνδυάστε με ρητό Module->import(...) όταν θέλετε να αναβάλετε ή να παρακάμψετε την αποστολή κατά τη μεταγλώττιση

  • package - ορίζει τον χώρο ονομάτων που μια μέθοδος import συμπληρώνει από την οπτική του καλούντος

  • caller - πώς μια μέθοδος import ανακαλύπτει σε ποιο πακέτο να εγκαταστήσει ονόματα

  • bless - άσχετη με την import, αλλά συχνά επικαλείται στα ίδια αρχεία αρθρωμάτων· και τα δύο διαμορφώνουν τον τρόπο με τον οποίο ένα πακέτο παρουσιάζεται στους χρήστες του