import#
לאכלס את מרחב השמות של הקורא בשמות שמודול בוחר לייצא.
import אינו פונקציה מובנית. הוא מתודת מחלקה שמודול מגדיר כך של־use יהיה היכן להעביר את רשימת הארגומנטים. כאשר כותבים use Module LIST, Perl טוען את המודול ואז קורא ל־Module->import(LIST) בזמן הידור, בחבילה שמכילה את הוראת ה־use. כל מה שהמתודה הזו עושה - להתקין תת־שגרות ב־stash של הקורא, להפוך ביטי תכונה, להגדיר דגלי פרגמה - הוא כל חוזה ה־import של המודול.
רוב המודולים לעולם לא כותבים import ביד; הם יורשים אותו מ־Exporter ומצהירים על @EXPORT / @EXPORT_OK במקום זאת. פרגמות (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רץ בעוד הקובץ העוטף עדיין מנותח. כל אבטיפוסי תת־שגרות או פרגמות לקסיקליות שהוא מתקין נראים לשאר הקובץ מאותה נקודה ואילך. כל מה שנעשה בזמן ריצה - פתיחת קבצים, קריאת תצורה - קורה מוקדם יותר ממה שקריאה נאיבית של המקור מציעה.callerמשקף את בלוק ה־BEGIN, לא את תת־השגרה הסובבת. מתודתimportשבוחנתcaller(0)רואה את החבילה שכתבהuse Module, וזה בדיוק מה שהיא רוצה; היא אינה רואה את תת־השגרה שמכילה את הוראת ה־use.רשימה נעדרת מול רשימה ריקה.
use Moduleללא רשימה קורא ל־Module->importללא ארגומנטים - המודול מתקין את ברירות המחדל שלו.use Module ()עם רשימה ריקה מפורשת מדלג על קריאת ה־importלחלוטין. זהו המבנה עבור ״לטעון את הקובץ אך לא לגעת במרחב השמות שלי.״
no Module LIST הוא תמונת המראה: הוא קורא ל־Module->unimport(LIST) במקום import. פרגמות משתמשות בזה כדי לכבות תכונות לתחום הלקסיקלי העוטף.
הגדרת מתודת 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
ייבוא מפרגמה - אפקט לקסיקלי בבלוק העוטף:
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.פרגמות בדרך כלל מתקינות מצב לקסיקלי, לא תת־שגרות ברמת חבילה. ה־
importשלהן קורא לפונקציות כמוwarnings::import_intoאו משנה את%^H; זוהי הסיבה שאפקט של פרגמה תחום לבלוק העוטף במקום להתמיד בחבילה.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
use- הטוען בזמן הידור שמפעיל אתimport; הבנת אחד דורשת את האחרno- המראה שלuse; קורא ל־unimportעם אותם כללי העברת ארגומנטיםrequire- טוען את הקובץ מבלי לקרוא ל־import; יש לשייך עםModule->import(...)מפורש כאשר רוצים לדחות או לדלג על הדיספאץ« בזמן הידורpackage- מגדיר את מרחב השמות שמתודתimportמאכלסת מנקודת המבט של הקוראcaller- איך מתודתimportמגלה לאיזו חבילה להתקין שמותbless- לא קשור ל־import, אך לעיתים קרובות מופעל באותם קבצי מודול; שניהם מעצבים איך חבילה מציגה את עצמה למשתמשים שלה