תיחום · מודולים · מחלקות ותכנות מונחה־עצמים

use#

טעינת מודול בזמן הידור וייבוא הסמלים שלו לחבילה הנוכחית.

use הוא המנגנון היומיומי למשיכת קוד ספריה. הוא רץ בזמן הידור, לא בזמן ריצה: המודול הנקוב ממוקם ב־@INC, נטען (אם אינו כבר ב־%INC), ומקבל הזדמנות לשנות את מרחב השמות של הקורא - בדרך כלל על־ידי aliasing של שמות תת־שגרה או משתנה אליו. אותו תחביר מניע גם פרגמות (הוראות מהדר כגון strict או warnings); ההבדל היחיד הוא מוסכמה - פרגמות הן באותיות קטנות ובדרך כלל יש להן אפקטים לקסיקליים, לא ברמת חבילה.

הצהרת use מוגדרת כשקולה בדיוק ל:

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

ה־BEGIN כופה שגם הטעינה וגם הייבוא יתרחשו בזמן שהקובץ הסובב עדיין מפורסר, כך שהשמות המיובאים נראים למהדר עבור שאר הקובץ.

תקציר#

use Module VERSION LIST
use Module VERSION
use Module LIST
use Module
use Module ()
use VERSION

מה מוחזר#

use הוא הצהרה, לא ביטוי - אין לו ערך החזרה שימושי ואינו יכול להופיע בצד ימין של דבר. האפקט שלו הוא תופעת לוואי על יחידת ההידור הנוכחית: %INC של החבילה מקבל ערך, החבילה המייבאת מקבלת אילו סמלים ש־import ייבא אליה, ו־ - עבור use VERSION - התחום הלקסיקלי הנוכחי מקבל חבילת תכונות שמופעלת.

אם המודול אינו ניתן לטעינה, או אם import מת, בלוק ה־BEGIN מפיץ את החריגה וההידור נקטע.

ארבע צורות המודול#

use Module#

טוען את המודול וקורא למתודה import שלו ללא ארגומנטים. המודול מחליט מה ״ללא ארגומנטים״ אומר; עבור מודולים מבוססי־Exporter זה בדרך כלל אומר ״יצוא ברירות המחדל של @EXPORT שלך״:

use File::Spec;                 # calls File::Spec->import()

use Module LIST#

טוען את המודול וקורא ל־import עם LIST:

use List::Util qw(first sum max);

זו הצורה הנפוצה של ״לייבא בדיוק את השמות האלה״. LIST מועברת מילולית ל־import; משמעותה היא עניינו של המודול, לא של השפה.

use Module ()#

סוגריים ריקים מבטלים את קריאת ה־import לחלוטין. זה שונה מהשמטת הרשימה - אף מתודת import אינה מופעלת כלל:

use POSIX ();                   # load, but do not import anything
POSIX::strftime(...);           # call by full name instead

שקול ל:

BEGIN { require POSIX }

יש להשתמש בזה כאשר רוצים שהמודול ייטען אך לא רוצים שמרחב השמות שלכם ישתנה - בדרך כלל משום שתקראו לכל דבר בשם המוסמך במלואו, או משום שיצואי ברירת המחדל של המודול ידרסו משהו שחשוב לכם.

use Module VERSION / use Module VERSION LIST#

כאשר VERSION מופיע מיד אחרי Module (ללא פסיק), use קורא למתודה VERSION של המודול עם אותה גרסה כארגומנט לפני קריאה ל־import:

use List::Util 1.45 qw(uniq);

שקול ל:

BEGIN {
    require List::Util;
    List::Util->VERSION(1.45);
    List::Util->import(qw(uniq));
}

מתודת VERSION ברירת המחדל, הנירשה מ־UNIVERSAL, מקרקרת אם הגרסה המבוקשת גדולה מ־$Module::VERSION.

VERSION חייב להיראות כליטרל גרסה - ספרה, או v ואחריה ספרה. ביטויים שרירותיים במיקום ההוא מפורסרים כתחילת LIST, לא כגרסה. שימו לב שאין פסיק אחרי VERSION.

use VERSION - בקשת רמת שפה של Perl#

use VERSION (ללא שם מודול) מצהיר על גרסת ה־Perl המינימלית שהקובץ דורש, ומפעיל לקסיקלית את חבילת התכונות התואמת:

use v5.36;                      # v-string form - preferred
use 5.036;                      # numeric form - equivalent
use 5.036_000;                  # older numeric form

חריגה נזרקת בזמן הידור אם ה־Perl הרץ ישן יותר מ־VERSION; שאר הקובץ אינו אפילו מפורסר.

מעבר לבדיקת הגרסה, use VERSION מדליק את התכונות החבולות עם אותה מהדורה:

  • use v5.12 ומעלה - use strict מובלע.

  • use v5.35 ומעלה - use warnings מובלע.

  • use v5.36 - קו הבסיס המודרני הנפוץ: מוסיף say, signatures, isa, ותכונות החבילות הקודמות.

  • use v5.39 ומעלה - מייבא לקסיקלית פונקציות builtin עבור החבילה התואמת.

  • use v5.41 ומעלה - מפעיל את source::encoding 'ascii'.

use VERSION אינו טוען את feature.pm, strict.pm, warnings.pm, או builtin.pm - הוא מממש את ההתנהגות השקולה ישירות. יש למקם אותו בראש הקובץ, לפני כל דבר שתלוי בכך שאותן תכונות פעילות.

מ־Perl 5.39 ואילך, הוצאת use VERSION שני בעוד אחד כבר בתוקף היא שגיאה קטלנית. בחבילות ישנות יותר זה היה רק deprecated.

מודולים מול פרגמות#

תחבירית, פרגמות ומודולים זהים - שניהם רק חבילות שאת המתודה import שלהן מפעילים דרך use. ההבדלים המוסכמים:

  • שמות. פרגמות הן באותיות קטנות (strict, warnings, feature, integer); מודולים הם Studly::Caps.

  • תחום אפקט. פרגמות בדרך כלל משנות את התחום הלקסיקלי הנוכחי (בלוק, לא חבילה) ומשתחררות בסוגר הסוגר. מודולים בדרך כלל משנים את החבילה הנוכחית ונמשכים עד סוף הקובץ.

  • no. ההצהרה המקבילה no קוראת ל־unimport במקום ל־import. פרגמות בדרך כלל מממשות unimport כדי לבטל את האפקט שלהן; רוב המודולים הרגילים לא.

use strict;                     # lexical - affects this block / file
use warnings;                   # lexical
{
    no warnings 'uninitialized';
    # warnings off only in this block
}

use List::Util qw(sum);         # package-scoped - affects main::

טעינה מותנית#

משום ש־use רץ בזמן הידור, הוא מתעלם מזרימת בקרה רגילה של זמן ריצה. use בתוך הענף השקרי של if עדיין מבוצע:

if (0) {
    use Heavy::Module;          # loaded anyway - compile time!
}

לטעינה מותנית באמת, יש להשתמש ב־require בזמן ריצה, או לאצֵל לפרגמה if:

use if $] >= 5.036, 'experimental', 'builtin';
use if $^O eq 'MSWin32', 'Win32::API';

דוגמאות#

טעינת מודול עם יצואי ברירת המחדל שלו:

use Carp;                       # croak, carp, confess visible here

ייבוא תת־קבוצה מסוימת:

use List::Util qw(first min max sum);

טעינה ללא ייבוא - קריאה בשם מלא:

use Scalar::Util ();
my $ok = Scalar::Util::looks_like_number($x);

דרישת גרסת מודול מינימלית:

use Moo 2.000000;

הצהרת רמת שפת Perl וקבלת חבילת התכונות שלה:

use v5.36;                      # strict, warnings, say, signatures...
sub greet ($name) {
    say "hello, $name";
}

הדלקת פרגמה לקובץ, ואז כיבוי לבלוק אחד:

use warnings;

sub legacy_parser {
    no warnings 'uninitialized';
    return join ",", @_;        # undefs render as "" without warnings
}

פרגמה מותנית דרך העזר if:

use if $] < 5.010, 'MRO::Compat';

מקרי קצה#

  • Module חייב להיות bareword. use $name; היא שגיאת תחביר - use אינו מקבל ביטוי זמן ריצה לשם המודול. יש להשתמש ב־require לכך.

  • אין פסיק בין Module ל־VERSION. use List::Util 1.45 היא בדיקת גרסה; use List::Util, 1.45 היא שגיאת תחביר.

  • כלל ליטרל הגרסה קפדני. כל דבר שאינו מתחיל בספרה או ב־v ואחריה ספרה מפורסר כתחילת LIST, לא כגרסה. use Module "1.45" מעביר את המחרוזת "1.45" ל־import; הוא אינו בודק גרסה.

  • LIST ריקה מול LIST מושמטת. use Module; קורא ל־Module->import(). use Module (); אינו קורא ל־import כלל. ההבחנה משמעותית עבור מודולים שה־import שלהם מייצר תופעות לוואי גם ללא ארגומנטים.

  • מתודת import חסרה. אם המודול אינו מגדיר (ואינו יורש) מתודת import, הקריאה נדחית בשקט - ללא שגיאה, גם אם AUTOLOAD מוגדר.

  • use בתוך eval. BEGIN רץ בזמן הידור של הקוד שעובר eval, כך ש־eval "use Some::Module" דוחה את הטעינה עד שה־eval רץ. זוהי הדרך הנפוצה לבחון מודול אופציונלי בזמן ריצה:

    eval { require Some::Module; Some::Module->import };
    my $have_it = !$@;
    
  • סדר use VERSION ופרגמות אחרות. יש למקם את use VERSION ראשון, כך שחבילת התכונות בתוקף לפני שפרגמות מאוחרות יותר (שעלולות לתלות בה) רצות. no strict 'refs' מאוחר יותר עדיין דורס את ההגבלות המובלעות על־ידי use v5.12+, אך הסתמכות על כך אינה מומלצת.

  • פרגמות שנראות כמו מודולים. חלק מהפרגמות מסופקות עם שם באות גדולה (UNIVERSAL, Internals); חלק מהמודולים מסופקים באותיות קטנות (if, lib, ok). מוסכמת השמות היא רמז, לא כלל - מה שחשוב הוא מה שה־import של המודול עושה.

הבדלים מהמעלה־הזרם#

תאימות מלאה עם Perl 5.42 מהמעלה־הזרם.

ראו גם#

  • require - החצי של זמן הריצה של use; טוען מודול ללא הפעלת import, ומקבל ביטוי זמן ריצה לשם המודול

  • no - ההצהרה המקבילה; קוראת ל־unimport במקום ל־import כדי לבטל את האפקט של פרגמה

  • import - אינו פונקציה מובנית; מתודת מחלקה רגילה המופעלת על־ידי use, בדרך כלל מסופקת דרך ירושה מ־Exporter

  • package - מצהירה על החבילה שמרחב השמות שלה ישונה על־ידי use

  • @INC - רשימת הספריות הנחפשות עבור קובץ המודול

  • %INC - רושם כל קובץ שנטען על־ידי use או require, ממופתח לפי נתיב יחסי