Scroll to navigation

PERLFUNC(1) دليل مرجع مبرمجي بيرل PERLFUNC(1)

الاسم

perlfunc - دوال بيرل المدمجة

الوصف

يمكن للدوال في هذا القسم أن تعمل كحدود في تعبير برمجي. وهي تنقسم إلى فئتين رئيسيتين: معاملات القائمة (list operators) والمعاملات الأحادية المسماة (named unary operators). وتختلف هذه المعاملات في علاقة أسبقيتها مع الفاصلة التي تليها. (انظر جدول الأسبقية في perlop). تأخذ معاملات القائمة أكثر من معامل واحد، بينما لا يمكن للمعاملات الأحادية أن تأخذ أكثر من معامل واحد أبدًا. وبالتالي، تنهي الفاصلة معامل المشغل الأحادي، لكنها تكتفي بالفصل بين معاملات مشغل القائمة. يوفر المشغل الأحادي عمومًا سياقًا قياسيًا (scalar context) لمعامله، بينما قد يوفر مشغل القائمة سياقًا قياسيًا أو سياق قائمة لمعاملاته. إذا كان يوفر كلاهما، فإن المعاملات القياسية تأتي أولاً وتتبعها معامل القائمة، ولا يمكن أن يكون هناك سوى معامل قائمة واحد فقط من هذا القبيل. على سبيل المثال، تحتوي الدوال "splice" على ثلاثة معاملات قياسية تتبعها قائمة، بينما تحتوي "gethostbyname" على أربعة معاملات قياسية.

في أوصاف بناء الجملة التي تلي ذلك، تظهر معاملات القائمة التي تتوقع قائمة (وتوفر سياق قائمة لعناصر القائمة) مع استخدام LIST كمعامل. قد تتكون هذه القائمة من أي مزيج من المعاملات القياسية أو قيم القائمة؛ وسيتم تضمين قيم القائمة في القائمة كما لو تم إقحام كل عنصر فردي في تلك النقطة من القائمة، مما يشكل قيمة قائمة أطول أحادية البعد. يجب أن تفصل الفواصل بين العناصر الحرفية للقائمة.

يمكن استخدام أي دالة في القائمة أدناه سواء بأقواس أو بدونها حول معاملاتها. (تغفل أوصاف الصيغة الأقواس). إذا استخدمت الأقواس، فإن القاعدة البسيطة والمفاجئة أحياناً هي: إنها تبدو كدالة، إذن هي دالة، ولا تهم الأسبقية. خلاف ذلك، فهي عامل قائمة (list operator) أو عامل أحادي (unary operator)، والأسبقية تهم حينها. المسافات البيضاء بين الدالة والقوس الأيسر لا تُحتسب، لذا أحياناً يجب توخي الحذر:

    print 1+2+4;      # يطبع 7.
    print(1+2) + 4;   # يطبع 3.
    print (1+2)+4;    # يطبع 3 أيضًا!
    print +(1+2)+4;   # يطبع 7.
    print ((1+2)+4);  # يطبع 7.

إذا قمت بتشغيل Perl باستخدام توجيه "use warnings"، فيمكنه تحذيرك بشأن هذا الأمر. على سبيل المثال، ينتج السطر الثالث أعلاه ما يلي:

    fùسر (...) كدالة في - السطر 1.
    استخدام عديم الفائدة لجمع الأعداد الصحيحة في سياق فارغ في - السطر 1.

توجد بعض الدوال التي لا تأخذ أي معاملات على الإطلاق، وبالتالي لا تعمل كمعاملات أحادية ولا كمعاملات قائمة. تشمل هذه الدوال دالة "time" و"endpwent". على سبيل المثال، تعني "time+86_400" دائمًا "time() + 86_400".

بالنسبة للدوال التي يمكن استخدامها في سياق قياسي أو سياق قائمة، يُشار عادةً إلى الفشل غير المنهي في السياق القياسي عن طريق إرجاع القيمة غير المعرفة (undefined value)، وفي سياق القائمة عن طريق إرجاع قائمة فارغة.

تذكر القاعدة المهمة التالية: **لا توجد قاعدة** تربط سلوك تعبير ما في سياق القائمة بسلوكه في السياق القياسي، أو العكس. قد يقوم التعبير بشيئين مختلفين تمامًا. يقرر كل معامل ودالة نوع القيمة الأكثر ملاءمة لإرجاعها في السياق القياسي. تعيد بعض المعاملات طول القائمة التي كان سيتم إرجاعها في سياق القائمة. وتعيد بعض المعاملات القيمة الأولى في القائمة. وتعيد معاملات أخرى القيمة الأخيرة في القائمة. بينما تعيد بعض المعاملات عدد العمليات الناجحة. بشكل عام، تقوم هذه الدوال بما تريده، ما لم تكن تريد الاتساق.

تختلف المصفوفة المسماة في السياق السلمي (scalar context) تماماً عما قد يبدو للوهلة الأولى أنه قائمة في سياق سلمي. لا يمكنك جعل قائمة مثل "(1,2,3)" توجد في سياق سلمي، لأن المصرف (compiler) يعرف السياق في وقت التصريف. سيولد عامل الفاصلة السلمي هناك، وليس نسخة دمج القوائم من الفاصلة. هذا يعني أنها لم تكن أبداً قائمة منذ البداية.

بشكل عام، الدوال في بيرل التي تعمل كأغلفة لاستدعاءات النظام (system calls) التي تحمل نفس الاسم (مثل chown(2) و fork(2) و closedir(2) وغيرها) تعيد قيمة حقيقية (true) عند نجاحها وتعيد "undef" خلاف ذلك، كما هو مذكور عادةً في الأوصاف أدناه. هذا يختلف عن واجهات لغة C التي تعيد -1 عند الفشل. تشمل الاستثناءات لهذه القاعدة "wait" و "waitpid" و "syscall". كما تقوم استدعاءات النظام بتعيين المتغير الخاص $! عند الفشل، بينما لا تفعل الدوال الأخرى ذلك إلا بمحض الصدفة.

يمكن لوحدات التوسعة أيضاً الارتباط بمحلل Perl لتعريف أنواع جديدة من التعبيرات التي تبدأ بكلمات مفتاحية. قد تبدو هذه كدوال، ولكنها قد تبدو أيضاً مختلفة تماماً. الصيغة التي تتبع الكلمة المفتاحية يحددها الامتداد بالكامل. إذا كنت مطوراً، فانظر "PL_keyword_plugin" في perlapi لمعرفة الآلية. إذا كنت تستخدم مثل هذه الوحدة، فانظر توثيق الوحدة للحصول على تفاصيل الصيغة التي تعرفها.

دوال بيرل حسب الفئة

إليك دوان Perl (بما في ذلك الأشياء التي تبدو كدوال، مثل بعض الكلمات المفتاحية والعوامل المسماة) مرتبة حسب الفئة. تظهر بعض الدوال في أكثر من مكان. تُشرح أي تحذيرات، بما في ذلك تلك الناتجة عن الكلمات المفتاحية، في perldiag و warnings.

دوال للمتغيرات القياسية (SCALARs) أو النصوص
"chomp", "chop", "chr", "crypt", "fc", "hex", "index", "lc", "lcfirst", "length", "oct", "ord", "pack", "q//", "qq//", "reverse", "rindex", "sprintf", "substr", "tr///", "uc", "ucfirst", "y///"

دالة "fc" متاحة فقط إذا تم تمكين ميزة "fc" أو إذا كانت مسبوقة بـ "CORE::". يتم تمكين ميزة "fc" تلقائيًا عند التصريح عن استخدام "use v5.16" (أو إصدار أحدث) في النطاق الحالي.

التعبيرات النمطية ومطابقة الأنماط
"m//", "pos", "qr//", "quotemeta", "s///", "split", "study"
الدوال الرقمية
"abs", "atan2", "cos", "exp", "hex", "int", "log", "oct", "rand", "sin", "sqrt", "srand"
"each", "keys", "pop", "push", "shift", "splice", "unshift", "values"
دوال لبيانات القوائم
"all", "any", "grep", "join", "map", "qw//", "reverse", "sort", "unpack"
"delete", "each", "exists", "keys", "values"
دوال الإدخال والإخراج
"binmode", "close", "closedir", "dbmclose", "dbmopen", "die", "eof", "fileno", "flock", "format", "getc", "print", "printf", "read", "readdir", "readline", "rewinddir", "say", "seek", "seekdir", "select", "syscall", "sysread", "sysseek", "syswrite", "tell", "telldir", "truncate", "warn", "write"

دالة "say" متاحة فقط إذا تم تمكين ميزة "say" أو إذا كانت مسبوقة بـ "CORE::". يتم تمكين ميزة "say" تلقائيًا عند التصريح عن استخدام "use v5.10" (أو إصدار أحدث) في النطاق الحالي.

دوال للبيانات ثابتة الطول أو السجلات
"pack", "read", "syscall", "sysread", "sysseek", "syswrite", "unpack", "vec"
دوال لمقابض الملفات، الملفات، أو المجلدات
"-X", "chdir", "chmod", "chown", "chroot", "fcntl", "glob", "ioctl", "link", "lstat", "mkdir", "open", "opendir", "readlink", "rename", "rmdir", "select", "stat", "symlink", "sysopen", "umask", "unlink", "utime"
الكلمات المفتاحية المتعلقة بتدفق التحكم في برنامج بيرل
"break", "caller", "continue", "die", "do", "dump", "eval", "evalbytes", "exit", "__FILE__", "goto", "last", "__LINE__", "method", "next", "__PACKAGE__", "redo", "return", "sub", "__SUB__", "wantarray"

تتوفر "break" فقط إذا مُكنت ميزة "switch" التجريبية أو استُخدمت بادئة "CORE::". تمكن ميزة "switch" أيضًا عبارات "default" و "given" و "when"، الموثقة في "Switch Statements" في perlsyn. تُمكّن ميزة "switch" آليًا مع إعلان "use v5.10" (أو أعلى) في النطاق الحالي. في بيرل v5.14 وما قبله، تطلبت "continue" ميزة "switch"، مثل الكلمات المفتاحية الأخرى.

تتوفر "evalbytes" فقط مع ميزة "evalbytes" (راجع feature) أو إذا كانت مسبوقة بـ "CORE::". تتوفر "__SUB__" فقط مع ميزة "current_sub" أو إذا كانت مسبوقة بـ "CORE::". تُمكّن كل من ميزتي "evalbytes" و "current_sub" آليًا مع إعلان "use v5.16" (أو أعلى) في النطاق الحالي.

الكلمات المفتاحية المتعلقة بنطاق المتغيرات (scoping)
"caller", "class", "field", "import", "local", "my", "our", "package", "state", "use"

تتوفر "state" فقط إذا مُكنت ميزة "state" أو إذا كانت مسبوقة بـ "CORE::". تُمكّن ميزة "state" آليًا مع إعلان "use v5.10" (أو أعلى) في النطاق الحالي.

دوال متنوعة
"defined", "formline", "lock", "prototype", "reset", "scalar", "undef"
دوال للعمليات (processes) ومجموعات العمليات
"alarm", "exec", "fork", "getpgrp", "getppid", "getpriority", "kill", "pipe", "qx//", "readpipe", "setpgrp", "setpriority", "sleep", "system", "times", "wait", "waitpid"
الكلمات المفتاحية المتعلقة بوحدات بيرل (modules)
"do", "import", "no", "package", "require", "use"
الكلمات المفتاحية المتعلقة بالأصناف (classes) والبرمجة كائنية التوجه
"bless", "class", "__CLASS__", "dbmclose", "dbmopen", "field", "method", "package", "ref", "tie", "tied", "untie", "use"
دوال المقابس (sockets) منخفضة المستوى
"accept", "bind", "connect", "getpeername", "getsockname", "getsockopt", "listen", "recv", "send", "setsockopt", "shutdown", "socket", "socketpair"
دوال اتصال العمليات (IPC) لنظام System V
"msgctl", "msgget", "msgrcv", "msgsnd", "semctl", "semget", "semop", "shmctl", "shmget", "shmread", "shmwrite"
جلب معلومات المستخدم والمجموعة
"endgrent", "endhostent", "endnetent", "endpwent", "getgrent", "getgrgid", "getgrnam", "getlogin", "getpwent", "getpwnam", "getpwuid", "setgrent", "setpwent"
جلب معلومات الشبكة
"endprotoent", "endservent", "gethostbyaddr", "gethostbyname", "gethostent", "getnetbyaddr", "getnetbyname", "getnetent", "getprotobyname", "getprotobynumber", "getprotoent", "getservbyname", "getservbyport", "getservent", "sethostent", "setnetent", "setprotoent", "setservent"
الدوال المتعلقة بالوقت
"gmtime", "localtime", "time", "times"
الكلمات المفتاحية غير الدالية
"ADJUST", "and", "AUTOLOAD", "BEGIN", "catch", "CHECK", "cmp", "CORE", "__DATA__", "default", "defer", "DESTROY", "else", "elseif", "elsif", "END", "__END__", "eq", "finally", "for", "foreach", "ge", "given", "gt", "if", "INIT", "isa", "le", "lt", "ne", "not", "or", "try", "UNITCHECK", "unless", "until", "when", "while", "x", "xor"

قابلية النقل

ولدت لغة Perl في يونكس، وبالتالي يمكنها الوصول إلى جميع نداءات نظام يونكس الشائعة. في البيئات غير التابعة ليونكس، قد لا تتوفر وظائف بعض نداءات نظام يونكس أو قد تختلف تفاصيل الوظائف المتاحة قليلاً. دوال Perl المتأثرة بهذا هي:

"-X", "binmode", "chmod", "chown", "chroot", "crypt", "dbmclose", "dbmopen", "dump", "endgrent", "endhostent", "endnetent", "endprotoent", "endpwent", "endservent", "exec", "fcntl", "flock", "fork", "getgrent", "getgrgid", "gethostbyname", "gethostent", "getlogin", "getnetbyaddr", "getnetbyname", "getnetent", "getppid", "getpgrp", "getpriority", "getprotobynumber", "getprotoent", "getpwent", "getpwnam", "getpwuid", "getservbyport", "getservent", "getsockopt", "glob", "ioctl", "kill", "link", "lstat", "msgctl", "msgget", "msgrcv", "msgsnd", "open", "pipe", "readlink", "rename", "select", "semctl", "semget", "semop", "setgrent", "sethostent", "setnetent", "setpgrp", "setpriority", "setprotoent", "setpwent", "setservent", "setsockopt", "shmctl", "shmget", "shmread", "shmwrite", "socket", "socketpair", "stat", "symlink", "syscall", "sysopen", "system", "times", "truncate", "umask", "unlink", "utime", "wait", "waitpid"

لمزيد من المعلومات حول قابلية نقل هذه الدوال، راجع perlport وغيرها من الوثائق المتاحة الخاصة بالمنصة.

قائمة أبجدية لدوال بيرل

-X FILEHANDLE
-X EXPR
-X DIRHANDLE
اختبار ملف، حيث X هو أحد الحروف المدرجة أدناه. يأخذ هذا العامل الأحادي معاملاً واحداً، إما اسم ملف أو مقبض ملف (filehandle) أو مقبض دليل (dirhandle)، ويختبر الملف المرتبط لمعرفة ما إذا كان هناك شيء صحيح بشأنه. إذا حُذف المعامل، فإنه يختبر $_، باستثناء "-t" الذي يختبر STDIN. ما لم يوثق خلاف ذلك، فإنه يعيد 1 للتعبير عن الصواب و '' للتعبير عن الخطأ. إذا كان الملف غير موجود أو لا يمكن فحصه، فإنه يعيد "undef" ويضبط $! (errno). باستثناء اختبار "-l"، فإنها تتبع جميعاً الروابط الرمزية لأنها تستخدم stat() وليس lstat() (لذا لا يمكن فحص الروابط الرمزية المعلقة وبالتالي ستبلغ عن الفشل).

على الرغم من الأسماء المضحكة، فإن الأسبقية هي نفسها لأي معامل أحادي مسمى آخر. يمكن أن يكون المعامل أيًا مما يلي:

    -r  الملف قابل للقراءة بواسطة uid/gid الفعلي.
    -w  الملف قابل للكتابة بواسطة uid/gid الفعلي.
    -x  الملف قابل للتنفيذ بواسطة uid/gid الفعلي.
    -o  الملف مملوك من قبل uid الفعلي.
    -R  الملف قابل للقراءة بواسطة uid/gid الحقيقي.
    -W  الملف قابل للكتابة بواسطة uid/gid الحقيقي.
    -X  الملف قابل للتنفيذ بواسطة uid/gid الحقيقي.
    -O  الملف مملوك من قبل uid الحقيقي.
    -e  الملف موجود.
    -z  حجم الملف صفر (فارغ).
    -s  حجم الملف غير صفري (يعيد الحجم بالبايت).
    -f  الملف هو ملف عادي.
    -d  الملف هو دليل.
    -l  الملف هو رابط رمزي (خطأ إذا كانت الروابط الرمزية غير
        مدعومة من نظام ملفات).
    -p  الملف عبارة عن أنبوب مسمى (FIFO)، أو مقبض الملف عبارة عن أنبوب.
    -S  الملف عبارة عن مقبس.
    -b  الملف هو ملف خاص كتلي.
    -c  الملف هو ملف خاص محرفي.
    -t  تم فتح مقبض الملف إلى tty.
    -u  تم ضبط بت setuid للملف.
    -g  تم ضبط بت setgid للملف.
    -k  تم ضبط بت sticky للملف.
    -T  الملف هو ملف نصي ASCII أو UTF-8 (تخمين ارشادي).
    -B  الملف هو ملف "ثنائي" (عكس -T).
    -M  وقت بدء السكربت ناقص وقت تعديل الملف، بالأيام.
    -A  نفس الشيء بالنسبة لوقت الوصول.
    -C  نفس الشيء بالنسبة لوقت تغيير inode (يونكس، قد يختلف في منصات
        أخرى)
    

مثال:

    while (<>) {
        chomp;
        next unless -f $_;  # تجاهل الملفات الخاصة
        #...
    }
    

لاحظ أن "-s/a/b/" لا يقوم باستبدال منفي. ومع ذلك، فإن قول "-exp($foo)" لا يزال يعمل كما هو متوقع: فقط الأحرف المفردة التي تلي علامة الناقص تُفسر على أنها اختبارات ملف.

تُعفى هذه المعاملات من قاعدة "يبدو وكأنه دالة" الموضحة أعلاه. أي أن القوس المفتوح بعد المعامل لا يؤثر على مقدار الكود التالي الذي يشكل الوسيط. ضع الأقواس المفتوحة قبل المعامل لفصله عن الكود الذي يليه (ينطبق هذا فقط على المعاملات ذات الأسبقية الأعلى من المعاملات الأحادية بالطبع):

    -s($file) + 1024   # من المحتمل أن يكون خطأ؛ هو نفسه -s($file + 1024)
    (-s $file) + 1024  # صحيح
    

تفسير عوامل صلاحيات الملفات "-r" و "-R" و "-w" و "-W" و "-x" و "-X" يعتمد مبدئياً فقط على وضع الملف ومعرفات المستخدم (uids) ومعرفات المجموعات (gids) للمستخدم. قد تكون هناك أسباب أخرى تمنعك فعلياً من قراءة الملف أو كتابته أو تنفيذه: على سبيل المثال ضوابط الوصول لنظام ملفات الشبكة، وقوائم التحكم في الوصول (ACLs)، وأنظمة الملفات المخصصة للقراءة فقط، وتنسيقات الملفات التنفيذية غير المعترف بها. لاحظ أن استخدام هذه العوامل الستة المحددة للتحقق مما إذا كانت بعض العمليات ممكنة هو خطأ عادةً، لأنه قد يكون عرضة لظروف التسابق (race conditions).

لاحظ أيضًا أنه بالنسبة للمستخدم الخارق (superuser) على أنظمة الملفات المحلية، فإن اختبارات "-r" و "-R" و "-w" و "-W" تعيد دائمًا 1، و "-x" و "-X" تعيد 1 إذا ضُبط أي بت تنفيذ في الوضع. وبالتالي قد تحتاج السكربتات التي يشغلها المستخدم الخارق إلى إجراء "stat" لتحديد الوضع الفعلي للملف، أو تعيين uid الفعلي مؤقتًا لشيء آخر.

إذا كنت تستخدم قوائم التحكم في الوصول (ACLs)، فهناك براغما (pragma) تسمى "filetest" قد تعطي نتائج أكثر دقة من وحدات وضع "stat" المجردة. عند استخدام "use filetest 'access'"، فإن اختبارات الملفات المذكورة أعلاه تختبر ما إذا كان يمكن منح الصلاحية (أو عدم منحها) باستخدام عائلة استدعاءات النظام access(2). لاحظ أيضاً أن اختبارات "-x" و "-X" قد تعيد صواباً تحت هذه البراغما حتى لو لم تكن هناك بتات صلاحية تنفيذ مضبوطة (ولا أي قوائم ACL لصلاحية تنفيذ إضافية). يعود هذا الغرابة إلى تعريفات استدعاءات النظام الأساسية. لاحظ أيضاً أنه بسبب تنفيذ "use filetest 'access'"، فإن مقبض الملف الخاص "_" لن يخزن نتائج اختبارات الملفات في الخبيئة عند تفعيل هذه البراغما. اقرأ توثيق براغما "filetest" لمزيد من المعلومات.

يعمل الاختباران "-T" و "-B" كما يلي. تُفحص الكتلة الأولى أو نحو ذلك من الملف لمعرفة ما إذا كانت UTF-8 صالحة تتضمن أحرفاً غير ASCII. إذا كان الأمر كذلك، فهو ملف "-T". خلاف ذلك، يُفحص نفس الجزء من الملف بحثاً عن أحرف غريبة مثل أكواد التحكم الغريبة أو الأحرف التي تم ضبط البت العالي فيها. إذا كانت أكثر من ثلث الأحرف غريبة، فهو ملف "-B"؛ وخلاف ذلك فهو ملف "-T". أيضاً، أي ملف يحتوي على بايت صفري في الجزء المفحوص يعتبر ملفاً ثنائياً. (إذا نُفذ ضمن نطاق use locale يتضمن "LC_CTYPE"، فإن الأحرف الغريبة هي أي شيء ليس قابلاً للطباعة ولا مسافة في المحلية الحالية). إذا استُخدم "-T" أو "-B" على مقبض ملف، يُفحص مخزن الإدخال والإخراج الحالي بدلاً من الكتلة الأولى. يعيد كل من "-T" و "-B" صواباً في الملف الفارغ، أو الملف عند نهاية الملف (EOF) عند اختبار مقبض ملف. ولأنك تضطر لقراءة الملف لإجراء اختبار "-T"، ففي معظم الأحيان سترغب في استخدام "-f" ضد الملف أولاً، كما في "next unless -f $file && -T $file".

إذا أُعطي أي من اختبارات الملفات (أو عامل "stat" أو عامل "lstat") مقبض الملف الخاص المكون من شرطة سفلية وحيدة، فسيتم استخدام هيكل stat لاختبار الملف السابق (أو عامل "stat")، مما يوفر استدعاء نظام. (لا يعمل هذا مع "-t"، ويجب أن تتذكر أن "lstat" و "-l" تترك قيماً في هيكل stat للرابط الرمزي، وليس الملف الحقيقي). (أيضاً، إذا تم ملء مخزن stat بواسطة استدعاء "lstat"، فإن "-T" و "-B" سيعيدان ضبطه بنتائج "stat _"). مثال:

    print "Can do.\n" if -r $x || -w _ || -x _;
    stat($filename);
    print "Readable\n" if -r _;
    print "Writable\n" if -w _;
    print "Executable\n" if -x _;
    print "Setuid\n" if -u _;
    print "Setgid\n" if -g _;
    print "Sticky\n" if -k _;
    print "Text\n" if -T _;
    print "Binary\n" if -B _;
    

بدءًا من الإصدار 5.10.0 من Perl، وكشكل من أشكال التحسين الصرفي، يمكنك تكديس معاملات اختبار الملفات، بطريقة تجعل "-f -w -x $file" مكافئًا لـ "-x $file && -w _ && -f _". (هذا مجرد بناء جملة مزخرف: إذا استخدمت القيمة المعادة من "-f $file" كوسيط لمعامل اختبار ملف آخر، فلن يحدث أي سحر خاص.)

مشكلات قابلية النقل: "-X" في perlport.

لتجنب إرباك المستخدمين المحتملين لكودك بأخطاء نحوية غامضة، ضع شيئًا كهذا في الجزء العلوي من السكربت:

    use v5.10;  # حتى يمكن تكديس معاملات اختبار الملفات
    
abs VALUE
يعيد القيمة المطلقة لوسيطه. إذا حُذفت القيمة (VALUE)، يستخدم $_.
يقبل اتصال مقبس وارد، تمامًا كما يفعل accept(2). يعيد العنوان المجمع (packed address) إذا نجح، وخطأ بخلاف ذلك. انظر المثال في "Sockets: Client/Server Communication" في perlipc.

في الأنظمة التي تدعم علم الإغلاق عند التنفيذ (close-on-exec) في الملفات، سيُضبط العلم لواصف الملف المفتوح حديثًا، كما هو محدد بواسطة قيمة $^F. راجع "$^F" في perlvar.

alarm SECONDS
يرتب لتسليم إشارة SIGALRM إلى هذه العملية بعد انقضاء عدد محدد من ثواني الساعة الحائطية. إذا لم تُحدد الثواني (SECONDS)، تُستخدم القيمة المخزنة في $_. (في بعض الآلات، لسوء الحظ، قد يكون الوقت المنقضي أقل أو أكثر بمقدار ثانية واحدة مما حددته بسبب كيفية عد الثواني، وقد يؤخر جدولة العملية تسليم الإشارة بشكل أكبر.)

يمكن لمؤقت واحد فقط أن يعمل في وقت واحد. كل نداء يعطل المؤقت السابق، ويمكن تقديم وسيط بقيمة 0 لإلغاء المؤقت السابق دون بدء مؤقت جديد. القيمة المعادة هي مقدار الوقت المتبقي في المؤقت السابق.

للتأخيرات ذات الدقة الأعلى من ثانية واحدة، توفر وحدة Time::HiRes (من CPAN، وهي جزء من التوزيع القياسي بدءاً من Perl 5.8) دالة "ualarm". يمكنك أيضاً استخدام نسخة Perl ذات المعاملات الأربعة من "select" مع ترك المعاملات الثلاثة الأولى غير معرفة، أو قد تتمكن من استخدام واجهة "syscall" للوصول إلى setitimer(2) إذا كان نظامك يدعم ذلك. انظر perlfaq8 للتفاصيل.

عادة ما يكون من الخطأ الخلط بين نداءات "alarm" و "sleep"، لأن "sleep" قد تكون منفذة داخليًا في نظامك باستخدام "alarm".

إذا أردت استخدام "alarm" لإنهاء استدعاء نظام بانتهاء الوقت فأنت بحاجة لاستخدام زوج "eval"/"die". لا يمكنك الاعتماد على التنبيه (alarm) في جعل استدعاء النظام يفشل مع ضبط $! على "EINTR" لأن Perl يضبط معالجات إشارات لإعادة تشغيل استدعاءات النظام في بعض الأنظمة. استخدام "eval"/"die" يعمل دائماً، مع مراعاة التنبيهات المذكورة في "Signals" في perlipc.

    eval {
        local $SIG{ALRM} = sub { die "alarm\n" }; # ملاحظة: \n مطلوبة
        alarm $timeout;
        my $nread = sysread $socket, $buffer, $size;
        alarm 0;
    };
    if ($@) {
        die unless $@ eq "alarm\n";   # نشر الأخطاء غير المتوقعة
        # انتهى الوقت
    }
    else {
        # لم ينتهِ الوقت
    }
    

لمزيد من المعلومات راجع perlipc.

مشكلات قابلية النقل: "alarm" في perlport.

يقيم BLOCK لكل عنصر من LIST (مع ضبط $_ محلياً لكل عنصر) ويتحقق من صحة نتيجة تلك الكتلة. يعيد صواباً إذا جعل كل عنصر الكتلة تعيد صواباً، أو يعيد خطأً إذا جعل عنصر واحد على الأقل الكتلة تعيد خطأً.

بمجرد أن يجعل أي عنصر الكتلة تعيد خطأً، تُحدد نتيجة هذا العامل. سيقوم بالتقصير (short-circuit) في هذه الحالة ولن ينظر في أي عناصر أخرى.

عند استخدامه كشرط، يشبه هذا استخدام "grep" لعدّ أن كل قيمة تستوفي الشرط، باستثناء سلوك التقصير هذا.

    if( all { length $_ } @strings ) {
        say "كل السلاسل ليست فارغة";
    }
    

يعادل تقريباً

    if( @strings == grep { length $_ } @strings ) ...
    

هذا العامل متاح فقط إذا فُعلت ميزة "keyword_all".

يُعتبر حالياً تجريبياً، وسيقوم بإصدار تحذير وقت التصريف في الفئة "experimental::all" ما لم يتم إسكات تلك الفئة.

يقيم BLOCK لكل عنصر من LIST (مع ضبط $_ محلياً لكل عنصر) ويتحقق من صحة نتيجة تلك الكتلة. يعيد صواباً إذا جعل عنصر واحد على الأقل الكتلة تعيد صواباً، أو يعيد خطأً إذا لم يوجد أي عنصر يجعلها تعيد صواباً.

بمجرد أن يجعل أي عنصر الكتلة تعيد صواباً، تُحدد نتيجة هذا العامل. سيقوم بالتقصير في هذه الحالة ولن ينظر في أي عناصر أخرى.

عند استخدامه كشرط، يشبه هذا "grep"، باستثناء سلوك التقصير هذا.

    if( any { length $_ } @strings ) {
        say "سلسلة واحدة على الأقل ليست فارغة";
    }
    

يعادل تقريباً

    if( grep { length $_ } @strings ) ...
    

هذا العامل متاح فقط إذا فُعلت ميزة "keyword_any".

يُعتبر حالياً تجريبياً، وسيقوم بإصدار تحذير وقت التصريف في الفئة "experimental::any" ما لم يتم إسكات تلك الفئة.

تُرجع ظل الزاوية العكسي لـ Y/X في النطاق من -PI إلى PI.

بالنسبة لعملية الظل، يمكنك استخدام دالة "Math::Trig::tan"، أو استخدام العلاقة المعروفة:

    sub tan { sin($_[0]) / cos($_[0])  }
    

القيمة المعادة لـ "atan2(0,0)" محددة حسب التنفيذ؛ راجع صفحة الدليل atan2(3) الخاصة بنظامك لمزيد من المعلومات.

مشكلات قابلية النقل: "atan2" في perlport.

يربط عنوان شبكة بمقبس، تمامًا كما يفعل bind(2). يعيد قيمة صواب إذا نجح، وخطأ في حال خلاف ذلك. ينبغي أن يكون NAME عنوانًا محزومًا من النوع المناسب للمقبس. راجع الأمثلة في "Sockets: Client/Server Communication" في perlipc.
يرتب لـ FILEHANDLE ليُقرأ أو يُكتب في نمط "ثنائي" أو "نصي" على الأنظمة التي تميز فيها مكتبات وقت التشغيل بين الملفات الثنائية والنصية. إذا كان FILEHANDLE تعبيرًا، تُؤخذ القيمة على أنها اسم واصف الملف. يعيد قيمة صواب عند النجاح، وإلا فإنه يعيد "undef" ويضبط $! (errno).

في بعض الأنظمة (بشكل عام، الأنظمة القائمة على DOS و Windows) تكون "binmode" ضرورية عندما لا تعمل مع ملف نصي. من أجل قابلية النقل، من الجيد دائماً استخدامها عندما يكون ذلك مناسباً، وعدم استخدامها مطلقاً عندما لا تكون مناسبة. أيضاً، يمكن للأشخاص ضبط الإدخال والإخراج الخاص بهم ليكون مبدئياً بترميز UTF8 Unicode، وليس بايتات.

بمعنى آخر: بغض النظر عن المنصة، استخدم "binmode" على البيانات الثنائية، مثل الصور على سبيل المثال.

إذا وُجدت LAYER، فهي سلسلة نصية واحدة، ولكنها قد تحتوي على توجيهات متعددة. تغير هذه التوجيهات سلوك واصف الملف. عندما توجد LAYER، فإن استخدام binmode على ملف نصي يصبح منطقيًا.

إذا حُذفت الطبقة (LAYER) أو حُددت كـ ":raw"، فسيُجعل مقبض الملف مناسبًا لتمرير البيانات الثنائية. يتضمن ذلك إيقاف ترجمة CRLF الممكنة وتمييزها كبايتات (بدلاً من أحرف Unicode). لاحظ أنه على الرغم مما قد يُفهم في "Programming Perl" (الإصدار الثالث) أو في أي مكان آخر، فإن ":raw" ليس ببساطة عكس ":crlf". سيُعطل أيضًا الطبقات الأخرى التي قد تؤثر على الطبيعة الثنائية للتدفق. انظر PerlIO، والمناقشة حول متغير البيئة PERLIO في perlrun.

تسمى التوجيهات ":bytes" و ":crlf" و ":utf8" وأي توجيهات أخرى من النموذج ":..." بطبقات I/O. يمكن استخدام pragma الفتح (open) لإنشاء طبقات I/O مبدئية.

معامل LAYER لدالة "binmode" موصوف كـ "DISCIPLINE" في "Programming Perl, 3rd Edition". ومع ذلك، منذ نشر هذا الكتاب، المعروف لدى الكثيرين باسم "Camel III"، انتقل الإجماع على تسمية هذه الوظيفة من "discipline" إلى "layer". لذا تشير جميع وثائق هذا الإصدار من Perl إلى "الطبقات" (layers) بدلاً من "disciplines". والآن نعود إلى الوثائق المجدولة بانتظام...

لتمييز FILEHANDLE كـ UTF-8، استخدم ":utf8" أو :encoding(UTF-8). يقوم ":utf8" بمجرد وسم البيانات كـ UTF-8 دون مزيد من التحقق، بينما يتحقق :encoding(UTF-8) من البيانات لكونها UTF-8 صالحة فعليًا. يمكن العثور على مزيد من التفاصيل في PerlIO::encoding.

بشكل عام، يجب استدعاء "binmode" بعد "open" ولكن قبل إجراء أي عمليات إدخال وإخراج على مقبض الملف. استدعاء "binmode" يفرغ عادةً أي بيانات مخرجات مخزنة معلقة (وربما بيانات مدخلات معلقة) على المقبض. استثناء من ذلك هو طبقة ":encoding" التي تغير ترميز الأحرف المبدئي للمقبض. تحتاج طبقة ":encoding" أحياناً إلى أن تُستدعى في منتصف التدفق، وهي لا تفرغ التدفق. كما تقوم ":encoding" ضمناً بدفع طبقة ":utf8" فوق نفسها لأن Perl يعمل داخلياً على أحرف Unicode بترميز UTF8.

يتآمر نظام التشغيل، وبرامج تشغيل الأجهزة، ومكتبات C، ونظام وقت تشغيل Perl جميعًا للسماح للمبرمج بالتعامل مع محرف واحد ("\n") كخاتمة للسطر، بغض النظر عن التمثيل الخارجي. في العديد من أنظمة التشغيل، يتطابق تمثيل الملف النصي الأصيل مع التمثيل الداخلي، ولكن في بعض المنصات يتكون التمثيل الخارجي لـ "\n" من أكثر من محرف واحد.

تستخدم جميع متغيرات Unix و Mac OS (القديمة والجديدة) وملفات Stream_LF على VMS محرفاً واحداً لإنهاء كل سطر في التمثيل الخارجي للنص (حتى لو كان ذلك المحرف الواحد هو CARRIAGE RETURN في نكهات Mac OS القديمة قبل Darwin، و LINE FEED في Unix ومعظم ملفات VMS). في أنظمة أخرى مثل OS/2 و DOS ونكهات MS-Windows المختلفة، يرى برنامجك "\n" كـ "\cJ" بسيطة، ولكن ما يتم تخزينه في ملفات النص هما المحرفان "\cM\cJ". هذا يعني أنه إذا لم تستخدم "binmode" على هذه الأنظمة، فإن تسلسلات "\cM\cJ" على القرص سيتم تحويلها إلى "\n" عند الإدخال، وسيتم تحويل أي "\n" في برنامجك مرة أخرى إلى "\cM\cJ" عند الإخراج. هذا ما تريده لملفات النصوص، ولكنه قد يكون كارثياً للملفات الثنائية.

نتيجة أخرى لاستخدام "binmode" (في بعض الأنظمة) هي أن علامات نهاية الملف الخاصة ستُرى كجزء من دفق البيانات. بالنسبة للأنظمة من عائلة Microsoft، هذا يعني أنه إذا كانت بياناتك الثنائية تحتوي على "\cZ"، فسيعتبرها نظام الإدخال/الإخراج الفرعي نهاية الملف، ما لم تستخدم "binmode".

"binmode" مهمة ليس فقط لعمليات "readline" و "print"، ولكن أيضًا عند استخدام "read"، و "seek"، و "sysread"، و "syswrite" و "tell" (راجع perlport لمزيد من التفاصيل). راجع المتغيرات $/ و "$\" في perlvar لمعرفة كيفية ضبط تسلسلات إنهاء سطر الإدخال والإخراج يدويًا.

قضايا قابلية النقل: "binmode" في perlport.

تخبر "bless" لغة Perl بتمييز العنصر المشار إليه بواسطة "REF" ككائن في حزمة. يُفضل دائمًا إصدار المعاملين من "bless" ما لم يكن هناك سبب محدد لعدم استخدامه.
  • مباركة (Bless) العنصر المشار إليه في حزمة محددة (النموذج الموصى به):

        bless $ref, $package;
        

    يضيف نموذج المعاملين الكائن إلى الحزمة المحددة كمعامل ثانٍ.

  • مباركة العنصر المشار إليه في الحزمة "main":

        bless $ref, "";
        

    إذا كان المعامل الثاني سلسلة فارغة، تضيف "bless" الكائن إلى الحزمة "main".

  • مباركة العنصر المشار إليه في الحزمة الحالية (غير قابل للتوريث):

        bless $ref;
        

    إذا استُخدمت "bless" بدون معاملها الثاني، يُنشأ الكائن في الحزمة الحالية. ينبغي دائمًا توفير المعامل الثاني إذا كان من الممكن لصنف مشتق أن يرث طريقة تنفذ "bless". نظرًا لأنها مصدر محتمل للعلل، لا يُنصح باستخدام "bless" بمعامل واحد.

راجع perlobj لمزيد من المعلومات حول مباركة (blessing) الكائنات.

تعيد "bless" معاملها الأول، المرجع المقدم، كقيمة للدالة؛ وبما أن "bless" هي عادةً آخر شيء ينفذ في المنشئات (constructors)، فهذا يعني أن المرجع إلى الكائن يعاد كقيمة للمنشئ ويسمح لـ المستدعي (caller) باستخدام هذا الكائن المعاد فوراً في استدعاءات الطرق.

ينبغي أن يكون "CLASSNAME" دائمًا اسمًا مختلط الحالة (mixed-case)، حيث إن الأسماء المكتوبة بالكامل بأحرف كبيرة أو صغيرة مخصصة لأنواع Perl المدمجة والبرغمات على التوالي. تجنب إنشاء أسماء حزم بأحرف كبيرة فقط أو صغيرة فقط لمنع الارتباك.

تجنب أيضاً مباركة (blessing) الأشياء في اسم الفئة 0؛ سيؤدي ذلك إلى فشل الكود الذي يتحقق (خطأً) من نتيجة "ref" لمعرفة ما إذا كان المرجع مباركاً (blessed)، حيث يتم إرجاع "0" وهي قيمة خطأ.

راجع "Perl Modules" في perlmod لمزيد من التفاصيل.

الخروج من كتلة "given".

"break" متاحة فقط إذا كانت ميزة "switch" مفعلة أو إذا كانت مسبوقة بـ "CORE::". تُفعل ميزة "switch" آليًا بتصريح "use v5.10" (أو أعلى) في النطاق الحالي.

caller EXPR
يعيد سياق استدعاء دالة perl الصرفة الحالية. في السياق السلمي، يعيد اسم حزمة المستدعي (caller) إذا وجد مستدعي (أي إذا كنا في دالة فرعية أو "eval" أو "require") والقيمة غير المعرفة خلاف ذلك. لا تعيد "caller" أبداً دوال XS ويتم تخطيها. ستظهر دالة perl الصرفة التالية بدلاً من دالة XS في قيم إرجاع المستدعي. في سياق القائمة، يعيد المستدعي

       # 0         1          2
    my ($package, $filename, $line) = caller;
    

مثل "__FILE__" و "__LINE__"، قد يُعدل اسم الملف ورقم السطر المعاد هنا بواسطة الآلية الموضحة في "Plain Old Comments (Not!)" في perlsyn.

باستخدام EXPR، فإنه يعيد بعض المعلومات الإضافية التي يستخدمها المنقح لطباعة تتبع المكدس. تشير قيمة EXPR إلى عدد إطارات الاستدعاء التي يجب العودة إليها قبل الإطار الحالي.

    #  0         1          2      3            4
 my ($package, $filename, $line, $subroutine, $hasargs,
    #  5          6          7            8       9         10
    $wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash)
  = caller($i);
    

هنا، $subroutine هي الدالة التي استدعاها المستدعِي (بدلاً من الدالة التي تحتوي على المستدعِي). لاحظ أن $subroutine قد تكون "(eval)" إذا لم يكن الإطار استدعاء روتين فرعي، بل "eval". في مثل هذه الحالة، تُضبط العناصر الإضافية $evaltext و $is_require: $is_require يكون صوابًا إذا أُنشئ الإطار بواسطة عبارة "require" أو "use"، ويحتوي $evaltext على نص عبارة "eval EXPR". على وجه الخصوص، بالنسبة لعبارة "eval BLOCK"، تكون $subroutine هي "(eval)"، لكن $evaltext غير محدد. (لاحظ أيضًا أن كل عبارة "use" تنشئ إطار "require" داخل إطار "eval EXPR".) قد تكون $subroutine أيضًا "(unknown)" إذا حدث وحُذف هذا الروتين الفرعي المعين من جدول الرموز. يكون $hasargs صوابًا إذا أُنشئ مثيل جديد من @_ للإطار. يحتوي $hints و $bitmask على تلميحات برمجية جُمع المستدعِي بها. يتوافق $hints مع $^H، ويتوافق $bitmask مع "${^WARNING_BITS}". قيم $hints و $bitmask عرضة للتغيير بين إصدارات Perl، وليست مخصصة للاستخدام الخارجي.

و $hinthash هو مرجع لهش (hash) يحتوي على قيمة "%^H" عندما جُمع المستدعِي، أو "undef" إذا كان "%^H" فارغًا. لا تعدل قيم هذا الهش، لأنها القيم الفعلية المخزنة في optree.

لاحظ أن الأنواع الوحيدة من إطارات الاستدعاء المرئية هي استدعاءات الروتين الفرعي و "eval". أشكال السياق الأخرى، مثل حلقات "while" أو "foreach" أو كتل "try" لا تُعتبر مثيرة للاهتمام لـ "caller"، لأنها لا تغير سلوك تعبير "return".

علاوة على ذلك، عند الاستدعاء من داخل حزمة DB في سياق القائمة، ومع وسيط، يعيد المستدعِي معلومات أكثر تفصيلاً: يضبط متغير القائمة @DB::args ليكون الوسائط التي استُدعي بها الروتين الفرعي.

كن على علم بأن المحسّن (optimizer) قد يكون قد أزال إطارات الاستدعاء قبل أن تتاح لـ "caller" فرصة الحصول على المعلومات. وهذا يعني أن caller(N) قد لا يعيد معلومات حول إطار الاستدعاء الذي تتوقعه، بالنسبة لـ "N > 1". على وجه الخصوص، قد يحتوي @DB::args على معلومات من المرة السابقة التي استُدعي فيها "caller".

كن على علم بأن ضبط @DB::args هو بذل أقصى جهد، ومخصص لـ التنقيح (debugging) أو توليد تتبعات رجعية، ولا ينبغي الاعتماد عليه. على وجه الخصوص، بما أن @_ تحتوي على أسماء مستعارة لمعاملات المستدعي (caller)، فإن Perl لا يأخذ نسخة من @_، لذا ستحتوي @DB::args على التعديلات التي تجريها الدالة الفرعية على @_ أو محتوياتها، وليس القيم الأصلية وقت الاستدعاء. @DB::args، مثل @_، لا تحتفظ بمراجع صريحة لعناصرها، لذا في حالات معينة قد يتم تحرير عناصرها وإعادة تخصيصها لمتغيرات أخرى أو قيم مؤقتة. وأخيراً، هناك أثر جانبي للتنفيذ الحالي وهو أن تأثيرات "shift @_" يمكن إبطالها عادةً (لكن ليس "pop @_" أو عمليات الـ splicing الأخرى، وليس إذا تم أخذ مرجع لـ @_، ومع مراعاة التنبيه بشأن العناصر المعاد تخصيصها)، لذا @DB::args هي في الواقع هجين من الحالة الحالية والحالة الأولية لـ @_. المشتري يحذر.

chdir EXPR
chdir FILEHANDLE
chdir DIRHANDLE
يغير دليل العمل إلى EXPR، إذا كان ذلك ممكنًا. إذا حُذف EXPR، يغير إلى الدليل المحدد بواسطة $ENV{HOME}، إذا ضُبط؛ وإذا لم يكن كذلك، يغير إلى الدليل المحدد بواسطة $ENV{LOGDIR}. (بموجب VMS، يُتحقق أيضًا من المتغير $ENV{'SYS$LOGIN'}، ويستخدم إذا ضُبط.) إذا لم يُضبط أي منهما، فإن "chdir" لا يفعل شيئًا ويفشل. يعيد صوابًا عند النجاح، وخطأ بخلاف ذلك. انظر المثال تحت "die".

في الأنظمة التي تدعم fchdir(2)، يمكنك تمرير مقبض ملف أو مقبض دليل كمعامل. في الأنظمة التي لا تدعم fchdir(2)، يؤدي تمرير المقابض إلى إثارة استثناء.

يغير أذونات قائمة من الملفات. يجب أن يكون العنصر الأول من القائمة هو الوضع العددي، والذي يجب أن يكون رقمًا ثمانيًا، والذي لا ينبغي بالتأكيد أن يكون سلسلة من الأرقام الثمانية: 0644 جيد، لكن "0644" ليس كذلك. يعيد عدد الملفات التي وُفّق في تغييرها. انظر أيضًا "oct" إذا كان كل ما لديك هو سلسلة نصية.

    my $cnt = chmod 0755, "foo", "bar";
    chmod 0755, @executables;
    my $mode = "0644"; chmod $mode, "foo";      # !!! يضبط الوضع إلى
                                                # --w----r-T
    my $mode = "0644"; chmod oct($mode), "foo"; # هذا أفضل
    my $mode = 0644;   chmod $mode, "foo";      # هذا هو الأفضل
    

في الأنظمة التي تدعم fchmod(2)، يمكنك تمرير مقابض ملفات بين الملفات. في الأنظمة التي لا تدعم fchmod(2)، يؤدي تمرير مقابض الملفات إلى إثارة استثناء. يجب تمرير مقابض الملفات كـ globs أو مراجع globs ليتم التعرف عليها؛ تعتبر الكلمات المجردة (barewords) أسماء ملفات.

    open(my $fh, "<", "foo");
    my $perm = (stat $fh)[2] & 07777;
    chmod($perm | 0600, $fh);
    

يمكنك أيضًا استيراد ثوابت "S_I*" الرمزية من وحدة "Fcntl":

    use Fcntl qw( :mode );
    chmod S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, @executables;
    # مماثل لـ chmod 0755 في المثال أعلاه.
    

مشكلات قابلية النقل: "chmod" في perlport.

chomp VARIABLE
تزيل هذه النسخة الأكثر أماناً من "chop" أي سلسلة لاحقة تتطابق مع القيمة الحالية لـ $/ (المعروف أيضاً باسم $INPUT_RECORD_SEPARATOR في وحدة "English"). وتعيد العدد الإجمالي للمحارف التي أزيلت من جميع معاملاتها. تُستخدم غالباً لإزالة سطر جديد من نهاية سجل الإدخال عندما تخشى أن يكون السجل الأخير يفتقد لسطر جديد. عند استخدام وضع الفقرة ("$/ = ''")، فإنها تزيل جميع السطور الجديدة اللاحقة من السلسلة. عند استخدام وضع الارتشاف (slurp mode) ("$/ = undef") أو وضع السجل ثابت الطول ($/ هو مرجع لعدد صحيح أو ما شابه؛ انظر perlvar)، فإن "chomp" لن تزيل أي شيء. إذا حُذف VARIABLE، فإنها تقوم بـ chomp لـ $_. مثال:

    while (<>) {
        chomp;  # تجنب \n في الحقل الأخير
        my @array = split(/:/);
        # ...
    }
    

إذا كان VARIABLE مصفوفة مبعثرة (hash)، فإنه يزيل الأطراف من قيم المصفوفة، ولكن ليس مفاتيحها، ويعيد ضبط مكرر "each" في هذه العملية.

يمكنك في الواقع إجراء chomp لأي شيء يمثل lvalue، بما في ذلك التخصيص (assignment):

    chomp(my $cwd = `pwd`);
    chomp(my $answer = <STDIN>);
    

إذا قمت بتطبيق chomp على قائمة، فسيُطبق chomp على كل عنصر، ويُعاد إجمالي عدد الأحرف المحذوفة.

لاحظ أن الأقواس ضرورية عندما تقوم بـ chomp لأي شيء ليس متغيراً بسيطاً. هذا لأن "chomp $cwd = `pwd`;" يتم تفسيرها على أنها "(chomp $cwd) = `pwd`;"، بدلاً من "chomp( $cwd = `pwd` )" كما قد تتوقع. وبالمثل، "chomp $x, $y" يتم تفسيرها على أنها "chomp($x), $y" بدلاً من "chomp($x, $y)".

chop VARIABLE
يقطع المحرف الأخير من السلسلة ويعيد المحرف المقطوع. إنه أكثر كفاءة بكثير من "s/.$//s" لأنه لا يفحص السلسلة ولا ينسخها. إذا حُذف VARIABLE، يقطع $_. إذا كان VARIABLE مصفوفة مبعثرة، فإنه يقطع قيم المصفوفة، ولكن ليس مفاتيحها، ويعيد ضبط مكرر "each" في هذه العملية.

يمكنك في الواقع قطع أي شيء يمثل lvalue، بما في ذلك التخصيص.

إذا بترت قائمة، فسيُبتر كل عنصر فيها. وتُعاد قيمة آخر عملية "chop" فقط.

لاحظ أن "chop" تعيد المحرف الأخير. لإعادة كل المحارف باستثناء الأخير، استخدم "substr($string, 0, -1)".

انظر أيضًا "chomp".

تغير المالك (والمجموعة) لقائمة من الملفات. يجب أن يكون أول عنصرين في القائمة هما معرف المستخدم numeric ومعرف المجموعة numeric، بهذا الترتيب. تُفسر القيمة -1 في أي من الموضعين بواسطة معظم الأنظمة على أنها ترك تلك القيمة دون تغيير. تعيد عدد الملفات التي غُيرت بنجاح.

    my $cnt = chown $uid, $gid, 'foo', 'bar';
    chown $uid, $gid, @filenames;
    

في الأنظمة التي تدعم fchown(2)، يمكنك تمرير مقابض ملفات بين الملفات. في الأنظمة التي لا تدعم fchown(2)، يؤدي تمرير مقابض الملفات إلى إثارة استثناء. يجب تمرير مقابض الملفات كـ globs أو مراجع globs ليتم التعرف عليها؛ تعتبر الكلمات المجردة أسماء ملفات.

إليك مثال يبحث عن معرفات المستخدم (uids) غير الرقمية في ملف passwd:

    print "User: ";
    chomp(my $user = <STDIN>);
    print "Files: ";
    chomp(my $pattern = <STDIN>);
    my ($login,$pass,$uid,$gid) = getpwnam($user)
        or die "$user not in passwd file";
    my @ary = glob($pattern);  # expand filenames
    chown $uid, $gid, @ary;
    

في معظم الأنظمة، لا يُسمح لك بتغيير ملكية الملف إلا إذا كنت المستخدم الخارق (superuser)، على الرغم من أنه يجب أن تكون قادراً على تغيير المجموعة إلى أي من مجموعاتك الثانوية. في الأنظمة غير الآمنة، قد يتم تخفيف هذه القيود، ولكن هذا ليس افتراضاً قابلاً للنقل. في أنظمة POSIX، يمكنك كشف هذه الحالة بهذه الطريقة:

    use POSIX qw(pathconf _PC_CHOWN_RESTRICTED);
    my $can_chown_giveaway =
        ! pathconf($path_of_interest, _PC_CHOWN_RESTRICTED);
    

قضايا المحمولية: "chown" في perlport.

chr NUMBER
تعيد المحرف الذي يمثله ذلك الـ NUMBER في مجموعة المحارف. على سبيل المثال، chr(65) هي "A" سواء في ASCII أو Unicode، و chr(0x263a) هو وجه باسم في Unicode.

تعطي القيم السالبة محرف استبدال Unicode ‏(chr(0xfffd))، باستثناء ما هو تحت موجّه (pragma) البايتات، حيث تُستخدم الثماني بتات المنخفضة من القيمة (مبتورة إلى عدد صحيح).

إذا أُغفل الـ NUMBER، تُستخدم $_.

للعكس، استخدم "ord".

لاحظ أن المحارف من 128 إلى 255 (بما في ذلك) لا تُرمّز داخليًا كمبدئي بصيغة UTF-8 لأسباب تتعلق بالتوافقية مع الإصدارات السابقة.

انظر perlunicode للمزيد حول Unicode.

chroot FILENAME
تعمل هذه الدالة مثل استدعاء النظام الذي يحمل نفس الاسم: فهي تجعل الدليل المسمى هو دليل الجذر الجديد لجميع مسارات الأسماء الإضافية التي تبدأ بـ "/" بواسطة عمليتك وجميع توابعها. (لا يغير دليل عملك الحالي، والذي لا يتأثر). لأسباب أمنية، يقتصر هذا الاستدعاء على المستخدم الخارق. إذا حُذف FILENAME، يتم تنفيذ "chroot" إلى $_.

ملاحظة: من الإلزامي للأمن القيام بـ chdir("/") ‏("chdir" إلى المجلد الجذر) فورًا بعد "chroot"، وإلا فقد يكون مجلد العمل الحالي خارج الجذر الجديد.

قضايا المحمولية: "chroot" في perlport.

يعلن عن BLOCK أو بقية وحدة التصريف كونه في فضاء الأسماء (namespace) المعطى، والذي ينفذ فئة كائن (انظر perlclass). يتصرف هذا بشكل مشابه لـ "package"، باستثناء أن الحزمة المنشأة حديثاً تتصرف كفئة (class).
close FILEHANDLE
تغلق الملف أو الأنبوب المرتبط بمقبض الملف، وتفرغ خبيئات الإدخال والإخراج، وتغلق واصف ملف النظام. تعيد قيمة صواب إذا نجحت تلك العمليات، وإذا لم يبلغ عن أي خطأ بواسطة أي طبقة PerlIO، ولم يكن هناك خطأ موجود مسبقًا على مقبض الملف.

إذا كان هناك خطأ موجود مسبقًا على مقبض الملف، فستعيد close قيمة خطأ وسيُضبط $! على الخطأ الناتج عن العملية الفاشلة، لذا يمكنك استخدام قيمته بأمان عند التبليغ عن الخطأ.

تغلق مقبض الملف المحدد حاليًا إذا أُغفل المعطى.

ليس عليك إغلاق FILEHANDLE إذا كنت ستقوم فوراً بفتح "open" آخر عليه، لأن "open" تغلقه نيابة عنك. (انظر "open"). ومع ذلك، فإن الـ "close" الصريح لملف إدخال يعيد ضبط عداد الأسطر ($.)، بينما الإغلاق الضمني الذي يتم بواسطة "open" لا يفعل ذلك.

إذا كان مقبض الملف قادمًا من فتح أنبوبي (piped open)، فستعيد "close" قيمة خطأ إذا فشل أحد نداءات النظام الأخرى المعنية أو إذا خرج برنامجه بحالة غير صفرية. إذا كانت المشكلة الوحيدة هي خروج البرنامج بحالة غير صفرية، فسيُضبط $! على 0. يؤدي إغلاق الأنبوب أيضًا إلى انتظار العملية المنفذة على الأنبوب حتى تخرج -- في حال رغبت في الاطلاع على مخرجات الأنبوب بعد ذلك -- ويضع ضمنيًا قيمة حالة الخروج لذلك الأمر في $? و "${^CHILD_ERROR_NATIVE}".

إذا كانت هناك خيوط (threads) متعددة تعمل، فإن "close" على مقبض ملف من فتح أنبوبي تعيد قيمة صواب دون انتظار انتهاء العملية الابنة، إذا كان مقبض الملف لا يزال مفتوحًا في خيط آخر.

يؤدي إغلاق طرف القراءة من أنبوب (pipe) قبل أن تنتهي العملية التي تكتب إليه في الطرف الآخر من الكتابة إلى تلقي الكاتب إشارة SIGPIPE. إذا كان الطرف الآخر لا يمكنه التعامل مع ذلك، فتأكد من قراءة جميع البيانات قبل إغلاق الأنبوب.

مثال:

    open(OUTPUT, '|sort >foo')  # pipe to sort
        or die "Can't start sort: $!";
    #...                        # print stuff to output
    close OUTPUT                # wait for sort to finish
        or warn $! ? "Error closing sort pipe: $!"
                   : "Exit status $? from sort";
    open(INPUT, 'foo')          # get sort's results
        or die "Can't open 'foo' for input: $!";
    

قد يكون FILEHANDLE تعبيرًا يمكن استخدام قيمته كمقبض ملف غير مباشر، وعادة ما يكون اسم مقبض الملف الحقيقي أو مقبضًا وُلد آليًا (autovivified).

إذا حدث خطأ عندما تغلق perl مقبضًا ضمنيًا، فستنتج perl تحذيرًا. يؤدي استدعاء close صراحة على المقبض إلى منع ذلك التحذير.

تغلق مجلدًا فُتح بواسطة "opendir" وتعيد نجاح نداء النظام ذلك.
تحاول الاتصال بمقبس (socket) بعيد، تمامًا مثل connect(2). تعيد قيمة صواب إذا نجحت، وخطأ بخلاف ذلك. يجب أن يكون NAME عنوانًا محزومًا من النوع المناسب للمقبس. انظر الأمثلة في "المقابس: تواصل العميل/الخادم" في perlipc.
continue BLOCK
عندما تُتبع بـ BLOCK، تكون "continue" في الواقع عبارة تحكم في التدفق وليست دالة. إذا كان هناك BLOCK لـ "continue" مرفق بـ BLOCK (عادةً في "while" أو "foreach")، فإنه يُنفذ دائمًا قبل إعادة تقييم الشرط مباشرة، تمامًا مثل الجزء الثالث من حلقة "for" في لغة C. وبالتالي يمكن استخدامه لزيادة متغير الحلقة، حتى عندما تُستمر الحلقة عبر عبارة "next" (التي تشبه عبارة "continue" في C).

قد تظهر "last"، أو "next"، أو "redo" داخل كتلة "continue"؛ وتسلك "last" و "redo" كما لو أنهما نُفذتا داخل الكتلة الرئيسة. وكذلك ستفعل "next"، ولكن بما أنها ستنفذ كتلة "continue"، فقد يكون الأمر أكثر إثارة.

    while (EXPR) {
        ### redo تأتي دائمًا إلى هنا
        do_something;
    } continue {
        ### next تأتي دائمًا إلى هنا
        do_something_else;
        # ثم العودة إلى الأعلى لإعادة فحص EXPR
    }
    ### last تأتي دائمًا إلى هنا
    

إغفال قسم "continue" يعادل استخدام قسم فارغ، وهذا منطقي تمامًا، لذا تعود "next" مباشرة لفحص الشرط في أعلى الحلقة.

عندما لا يكون هناك BLOCK، تكون "continue" دالة تسقط عبر كتلة "when" أو "default" الحالية بدلاً من تكرار "foreach" محيطة ديناميكيًا أو الخروج من "given" محيطة معجميًا. في إصدار Perl 5.14 وما قبله، كان هذا الشكل من "continue" متاحًا فقط عند تفعيل ميزة "switch". انظر feature و "عبارات التبديل" في perlsyn لمزيد من المعلومات.

cos EXPR
تعيد جيب التمام (cosine) لـ EXPR (معبرًا عنه بالراديان). إذا أُغفل EXPR، تؤخذ جيب تمام $_.

لعملية جيب التمام العكسية، يمكنك استخدام دالة "Math::Trig::acos"، أو استخدام هذه العلاقة:

    sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ) }
    
يُنشئ سلسلة ملخص (digest) تماماً مثل دالة crypt(3) في مكتبة C (على افتراض أن لديك نسخة هناك لم تُستأصل لكونها ذخيرة محتملة).

"crypt" هي دالة هاش أحادية الاتجاه. تُحوّل PLAINTEXT (النص الصريح) وSALT (الملح) إلى سلسلة قصيرة تُسمى ملخصاً، وهي القيمة التي تُعاد. سيؤدي استخدام نفس الـ PLAINTEXT والـ SALT دائماً إلى إعادة السلسلة نفسها، ولكن لا توجد طريقة (معروفة) للحصول على الـ PLAINTEXT الأصلي من الهاش. التغييرات الطفيفة في الـ PLAINTEXT أو الـ SALT ستؤدي إلى تغييرات كبيرة في الملخص.

لا توجد دالة لفك التعمية (decrypt). هذه الدالة ليست مفيدة تماماً للتشفير (لهذا الغرض، ابحث عن وحدات Crypt في مرآة CPAN القريبة منك) واسم "crypt" هو تسمية خاطئة قليلاً. بدلاً من ذلك، تُستخدم في المقام الرئيس للتحقق مما إذا كان نصان متطابقين دون الحاجة لنقل أو تخزين النص نفسه. مثال على ذلك هو التحقق من تقديم كلمة مرور صحيحة. يتم تخزين ملخص (digest) كلمة المرور، وليس كلمة المرور نفسها. يكتب المستخدم كلمة مرور يتم تعميتها بـ "crypt" بنفس قيمة salt الملخص المخزن. إذا تطابق الملخصان، فإن كلمة المرور صحيحة.

عند التحقق من سلسلة ملخص موجودة، يجب استخدام الملخص نفسه كملح (مثل "crypt($plain, $digest) eq $digest"). إن الـ SALT المستخدم لإنشاء الملخص يكون مرئياً كجزء من الملخص. يضمن هذا أن "crypt" ستقوم بهاش السلسلة الجديدة بنفس الملح الموجود في الملخص. يسمح هذا لبرمجتك بالعمل مع "crypt" القياسية ومع التطبيقات الأكثر غرابة. وبعبارة أخرى، لا تفترض شيئاً عن السلسلة المعادة نفسها ولا عن عدد بايتات الـ SALT التي قد تكون مهمة.

تقليدياً، النتيجة هي سلسلة من 13 بايتاً: أول بايتين هما الملح، تتبعهما 11 بايتاً من المجموعة "[./0-9A-Za-z]"، وكانت أول ثمانية بايتات فقط من الـ PLAINTEXT هي المهمة. لكن مخططات الهاش البديلة (مثل MD5)، ومخططات الأمان عالية المستوى (مثل C2)، والتطبيقات على المنصات غير التابعة لـ Unix قد تنتج سلاسل مختلفة.

عند اختيار salt جديد، أنشئ سلسلة عشوائية من محرفين تأتي محارفهما من المجموعة "[./0-9A-Za-z]" (مثل "join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]"). مجموعة المحارف هذه هي مجرد توصية؛ المحارف المسموح بها في salt تعتمد فقط على مكتبة crypt في نظامك، ولا يمكن لـ Perl تقييد قيم salt التي تقبلها "crypt".

إليك مثال يتأكد من أن من يقوم بتشغيل هذا البرنامج يعرف كلمة مروره:

    my $pwd = (getpwuid($<))[1];
    system "stty -echo";
    print "Password: ";
    chomp(my $word = <STDIN>);
    print "\n";
    system "stty echo";
    if (crypt($word, $pwd) ne $pwd) {
        die "Sorry...\n";
    } else {
        print "ok\n";
    }
    

بالطبع، كتابة كلمة مرورك الخاصة لأي شخص يطلبها منك هو أمر غير حكيم.

دالة "crypt" غير مناسبة لتجزئة (hashing) كميات كبيرة من البيانات، وليس أقلها أنه لا يمكنك استرجاع المعلومات مرة أخرى. انظر إلى وحدة Digest للحصول على خوارزميات أكثر قوة.

إذا استخدمت "crypt" على سلسلة Unicode (التي يُحتمل أن تحتوي على أحرف بنقاط ترميز فوق 255)، تحاول Perl فهم الموقف بمحاولة خفض رتبة (نسخة من) السلسلة إلى سلسلة بايتات من ثمانية بتات قبل استدعاء "crypt" (على تلك النسخة). إذا نجح ذلك، فبها ونعمت. وإلا، فإن "crypt" تتوقف مع رسالة "Wide character in crypt".

قضايا النقل: "crypt" في perlport.

[حلت دالة "untie" محل هذه الدالة بشكل كبير.]

يفك الارتباط بين ملف DBM وهاش.

قضايا النقل: "dbmclose" في perlport.

[حلت دالة "tie" محل هذه الدالة بشكل كبير.]

يربط هذا ملف dbm(3) أو ndbm(3) أو sdbm(3) أو gdbm(3) أو Berkeley DB بمصفوفة مبعثرة (hash). HASH هو اسم المصفوفة. (على عكس "open" العادي، المعامل الأول ليس مقبض ملف، على الرغم من أنه يبدو كذلك). DBNAME هو اسم قاعدة البيانات (بدون امتداد .dir أو .pag إن وجد). إذا كانت قاعدة البيانات غير موجودة، فسيتم إنشاؤها بالحماية المحددة بواسطة MASK (كما يتم تعديلها بواسطة "umask"). لمنع إنشاء قاعدة البيانات إذا لم تكن موجودة، يمكنك تحديد MASK بقيمة 0، وستعيد الدالة قيمة خطأ إذا لم تتمكن من العثور على قاعدة بيانات موجودة. إذا كان نظامك يدعم دوال DBM القديمة فقط، فيمكنك إجراء استدعاء "dbmopen" واحد فقط في برنامجك. في إصدارات Perl القديمة، إذا لم يكن نظامك يحتوي على DBM ولا ndbm، فإن استدعاء "dbmopen" ينتج خطأً فادحاً؛ أما الآن فإنه يعود لاستخدام sdbm(3).

إذا لم يكن لديك صلاحية وصول للكتابة إلى ملف DBM، يمكنك فقط قراءة متغيرات المصفوفة المبعثرة، وليس تعيينها. إذا كنت تريد اختبار ما إذا كان بإمكانك الكتابة، فإما أن تستخدم اختبارات الملفات أو تحاول تعيين مدخل مصفوفة وهمي داخل "eval" لالتقاط الخطأ.

لاحظ أن دوالاً مثل "keys" و "values" قد تعيد قوائم ضخمة عند استخدامها على ملفات DBM كبيرة. قد تفضل استخدام دالة "each" للتكرار عبر ملفات DBM كبيرة. مثال:

    # print out history file offsets
    dbmopen(%HIST,'/usr/lib/news/history',0666);
    while (($key,$val) = each %HIST) {
        print $key, ' = ', unpack('L',$val), "\n";
    }
    dbmclose(%HIST);
    

انظر أيضاً AnyDBM_File للحصول على وصف أكثر عمومية لإيجابيات وسلبيات مناهج dbm المختلفة، بالإضافة إلى DB_File لتطبيق غني بشكل خاص.

يمكنك التحكم في مكتبة DBM التي تستخدمها عن طريق تحميل تلك المكتبة قبل استدعاء "dbmopen":

    use DB_File;
    dbmopen(%NS_Hist, "$ENV{HOME}/.netscape/history.db")
        or die "Can't open netscape history file: $!";
    

قضايا النقل: "dbmopen" في perlport.

defined EXPR
تعيد قيمة منطقية تخبر ما إذا كان لـ EXPR قيمة غير القيمة غير المعرفة "undef". إذا لم يكن EXPR موجوداً، يُفحص $_.

تعيد العديد من العمليات "undef" للإشارة إلى الفشل، أو نهاية الملف، أو خطأ في النظام، أو متغير غير مهيأ، وظروف استثنائية أخرى. تسمح لك هذه الدالة بتمييز "undef" عن القيم الأخرى. (الاختبار المنطقي البسيط لن يميز بين "undef"، والصفر، والسلسلة الفارغة، و "0"، والتي تعتبر جميعاً خاطئة بالتساوي). لاحظ أنه بما أن "undef" هي قيمة سلمية صالحة، فإن وجودها لا يشير بالضرورة إلى حالة استثنائية: تعيد "pop" القيمة "undef" عندما يكون معاملها مصفوفة فارغة، أو عندما يكون العنصر المطلوب إرجاعه هو "undef".

يمكنك أيضاً استخدام defined(&func) للتحقق مما إذا كان قد سُمي الروتين الفرعي "func" من قبل. لا تتأثر القيمة المعادة بأي تصريحات أمامية لـ "func". قد يظل الروتين الفرعي الذي لم يُعرّف قابلاً للاستدعاء: قد تحتوي حزمته على طريقة "AUTOLOAD" تجعله ينبثق للوجود في المرة الأولى التي يُستدعى فيها؛ انظر perlsub.

استخدام "defined" على المجمعات (الهاشات والمصفوفات) لم يعد مدعوماً. كان يُستخدم للإبلاغ عما إذا كان قد خُصصت ذاكرة لهذا المجمع من قبل. بدلاً من ذلك، يجب استخدام اختبار بسيط للحجم:

    if (@an_array) { print "has array elements\n" }
    if (%a_hash)   { print "has hash members\n"   }
    

عند استخدامه على عنصر هاش، فإنه يخبرك ما إذا كانت القيمة معرفة، وليس ما إذا كان المفتاح موجوداً في الهاش. استخدم "exists" لهذا الغرض الأخير.

أمثلة:

    print if defined $switch{D};
    print "$val\n" while defined($val = pop(@ary));
    die "Can't readlink $sym: $!"
        unless defined($value = readlink $sym);
    sub foo { defined &$bar ? $bar->(@_) : die "No bar"; }
    $debugging = 0 unless defined $debugging;
    

ملاحظة: يميل الكثيرون إلى الإفراط في استخدام "defined" ثم يفاجئون عندما يكتشفون أن الرقم 0 و "" (السلسلة ذات الطول الصفري) هما في الواقع قيمتان معرّفتان. على سبيل المثال، إذا قلت

    "ab" =~ /a(.*)b/;
    

ينجح تطابق النمط ويتم تعريف $1، على الرغم من أنه طابق "لا شيء". لم يفشل حقاً في مطابقة أي شيء. بدلاً من ذلك، طابق شيئاً صدف أن طوله صفر محارف. هذا كله صريح وأمين جداً. عندما تعيد دالة قيمة غير معرفة، فهذا اعتراف بأنها لم تستطع إعطاءك إجابة صادقة. لذا يجب عليك استخدام "defined" فقط عند التشكيك في سلامة ما تحاول القيام به. في أوقات أخرى، المقارنة البسيطة بـ 0 أو "" هي ما تريده.

انظر أيضاً "undef"، و "exists"، و "ref".

بإعطاء تعبير يحدد عنصراً أو شريحة من الهاش، تقوم "delete" بحذف العناصر المحددة من ذلك الهاش بحيث لا تعود "exists" على ذلك العنصر تعيد قيمة صحيحة. ضبط عنصر هاش على القيمة غير المعرفة لا يزيل مفتاحه، لكن حذفه يفعل ذلك؛ انظر "exists".

في سياق القائمة، تعيد عادةً القيمة أو القيم المحذوفة، أو آخر عنصر من هذا القبيل في السياق السلمي. يتوافق طول قائمة الإرجاع مع طول قائمة المعاملات: حذف العناصر غير الموجودة يعيد القيمة غير المعرفة في مواضعها المقابلة. منذ Perl 5.28، يمكن تمرير شريحة مصفوفة مبعثرة من نوع مفتاح/قيمة إلى "delete"، وتكون قيمة الإرجاع هي قائمة من أزواج مفتاح/قيمة (عنصران لكل بند تم حذفه من المصفوفة المبعثرة).

يمكن أيضاً استخدام "delete" على المصفوفات وشرائح المصفوفات، لكن سلوكها أقل وضوحاً. على الرغم من أن "exists" ستعيد خطأً للمدخلات المحذوفة، فإن حذف عناصر المصفوفة لا يغير أبداً فهارس القيم الموجودة؛ استخدم "shift" أو "splice" لذلك. ومع ذلك، إذا وقعت أي عناصر محذوفة في نهاية المصفوفة، فإن حجم المصفوفة يتقلص إلى موضع أعلى عنصر لا يزال يختبر صواباً لـ "exists"، أو إلى 0 إذا لم يوجد أي عنصر. بعبارة أخرى، لن تحتوي المصفوفة على عناصر غير موجودة لاحقة بعد عملية الحذف.

تحذير: لا يُنصح بشدة باستدعاء "delete" على قيم المصفوفة. إن مفهوم حذف أو فحص وجود عناصر مصفوفة Perl ليس متسقاً من الناحية المفاهيمية، ويمكن أن يؤدي إلى سلوك مفاجئ.

الحذف من %ENV يعدل البيئة. الحذف من مصفوفة مبعثرة مرتبطة بملف DBM يحذف المدخل من ملف DBM. الحذف من مصفوفة مبعثرة أو مصفوفة "tied" قد لا يعيد بالضرورة أي شيء؛ يعتمد ذلك على تنفيذ طريقة DELETE في الحزمة "tied"، والتي قد تفعل ما تشاء.

تعبير "delete local EXPR" يجعل الحذف محلياً للكتلة الحالية في وقت التشغيل. حتى تخرج الكتلة، فإن العناصر المحذوفة محلياً تتوقف عن الوجود مؤقتاً. انظر "Localized deletion of elements of composite types" في perlsub.

    my %hash = (foo => 11, bar => 22, baz => 33);
    my $scalar = delete $hash{foo};         # $scalar is 11
    $scalar = delete @hash{qw(foo bar)}; # $scalar is 22
    my @array  = delete @hash{qw(foo baz)}; # @array  is (undef,33)
    

ما يلي يحذف (بشكل غير فعال) جميع قيم %HASH و @ARRAY:

    foreach my $key (keys %HASH) {
        delete $HASH{$key};
    }
    foreach my $index (0 .. $#ARRAY) {
        delete $ARRAY[$index];
    }
    

وكذلك تفعل هذه:

    delete @HASH{keys %HASH};
    delete @ARRAY[0 .. $#ARRAY];
    

لكن كلاهما أبطأ من إسناد القائمة الفارغة أو إلغاء تعريف %HASH أو @ARRAY، وهو الطريق المعتاد لتفريغ مجمع:

    %HASH = ();     # completely empty %HASH
    undef %HASH;    # forget %HASH ever existed
    @ARRAY = ();    # completely empty @ARRAY
    undef @ARRAY;   # forget @ARRAY ever existed
    

يمكن أن يكون EXPR معقداً بشكل عشوائي بشرط أن تكون عمليته النهائية هي عنصر أو شريحة من مجمع:

    delete $ref->[$x][$y]{$key};
    delete $ref->[$x][$y]->@{$key1, $key2, @morekeys};
    delete $ref->[$x][$y][$index];
    delete $ref->[$x][$y]->@[$index1, $index2, @moreindices];
    
تثير "die" استثناءً. داخل "eval"، يُحشى الاستثناء في $@ وتُنهى "eval" بالقيمة غير المعرفة. إذا كان الاستثناء خارج جميع كتل "eval" المحيطة، فسيُطبع الاستثناء غير الممسوك في "STDERR" وتخرج Perl بكود خروج يشير إلى الفشل. إذا كنت بحاجة إلى الخروج من العملية بكود خروج محدد، فانظر "exit".

أمثلة مكافئة:

    die "Can't cd to spool: $!\n" unless chdir '/usr/spool/news';
    chdir '/usr/spool/news' or die "Can't cd to spool: $!\n"
    

في معظم الأوقات، تُستدعى "die" مع سلسلة لاستخدامها كاستثناء. يمكنك إما إعطاء معامل واحد غير مرجعي ليعمل كاستثناء، أو قائمة من عنصرين أو أكثر، حيث ستُحول إلى سلاسل وتُدمج معاً لتشكيل الاستثناء.

إذا لم تنتهِ سلسلة الاستثناء بسطر جديد، فسيُلحق بها رقم سطر السكربت الحالي ورقم سطر الإدخال (إن وجد) وسطر جديد. لاحظ أن "رقم سطر الإدخال" (المعروف أيضاً باسم "القطعة") يخضع لأي مفهوم لـ "السطر" يكون سارياً حالياً، وهو متاح أيضاً كمتغير خاص $.. انظر "$/" في perlvar و "$." في perlvar.

تلميح: أحياناً يؤدي إلحاق ", stopped" برسالتك إلى جعلها أكثر منطقية عند إلحاق السلسلة "at foo line 123". لنفترض أنك تشغل سكربت "canasta".

    die "/etc/games is no good";
    die "/etc/games is no good, stopped";
    

ينتج عنهما، على التوالي

    /etc/games is no good at canasta line 123.
    /etc/games is no good, stopped at canasta line 123.
    

إذا كانت LIST فارغة أو كونت سلسلة فارغة، وكانت $@ تحتوي بالفعل على قيمة استثناء (عادةً من "eval" سابقة)، فسيُعاد استخدام تلك القيمة بعد إلحاق "\t...propagated". هذا مفيد لنشر الاستثناءات:

    eval { ... };
    die unless $@ =~ /Expected exception/;
    

إذا كانت LIST فارغة أو كونت سلسلة فارغة، وكانت $@ تحتوي على مرجع كائن له طريقة "PROPAGATE"، فسيُستدعى هذا الأسلوب مع بارامترات إضافية للملف ورقم السطر. تحل القيمة المعادة محل القيمة في $@؛ أي كما لو أنه قد استُدعي "$@ = eval { $@->PROPAGATE(__FILE__, __LINE__) };".

إذا كانت LIST فارغة أو كونت سلسلة فارغة، وكانت $@ فارغة أيضاً، فستُستخدم السلسلة "Died".

يمكنك أيضاً استدعاء "die" مع معطى مرجعي، وإذا صيد هذا داخل "eval"، فإن $@ ستحتوي على ذلك المرجع. يسمح هذا بمعالجة أكثر تفصيلاً للاستثناءات باستخدام كائنات تحافظ على حالة عشوائية حول الاستثناء. مثل هذا المخطط يفضل أحياناً على مطابقة قيم نصية معينة في $@ باستخدام التعبيرات النمطية.

لأن Perl يحول رسائل الاستثناءات غير الملتقطة إلى سلاسل نصية قبل عرضها، فمن المحتمل أن ترغب في زيادة تحميل (overload) عمليات التحويل لسلاسل نصية على كائنات الاستثناء. انظر overload للحصول على تفاصيل حول ذلك. يجب أن تكون الرسالة المحولة غير فارغة، ويجب أن تنتهي بسطر جديد، من أجل التوافق مع معالجة استثناءات السلاسل النصية. أيضاً، لأن مرجع كائن الاستثناء لا يمكن تحويله لسلسلة نصية دون تدميره، فإن Perl لا يحاول إلحاق الموقع أو المعلومات الأخرى بمرجع الاستثناء. إذا كنت تريد معلومات الموقع مع كائن استثناء معقد، فسيتعين عليك ترتيب وضع معلومات الموقع في الكائن بنفسك.

لأن $@ متغير عام (global)، احذر من أن تحليل استثناء تم التقاطه بواسطة "eval" قد يستبدل المرجع في المتغير العام. من الأسهل عمل نسخة محلية من المرجع قبل أي تلاعبات. إليك مثال:

    use Scalar::Util "blessed";
    eval { ... ; die Some::Module::Exception->new( FOO => "bar" ) };
    if (my $ev_err = $@) {
        if (blessed($ev_err)
            && $ev_err->isa("Some::Module::Exception")) {
            # handle Some::Module::Exception
        }
        else {
            # handle all other possible exceptions
        }
    }
    

إذا أدى استثناء غير ممسوك إلى خروج المفسر، يُحدد كود الخروج من قيم $! و $? باستخدام هذا الكود الوهمي:

    exit $! if $!;              # errno
    exit $? >> 8 if $? >> 8;    # child exit status
    exit 255;                   # last resort
    

كما هو الحال مع "exit"، يتم ضبط $? قبل فك كدسة الاستدعاء؛ يمكن لأي معالجات "DESTROY" أو "END" بعد ذلك تغيير هذه القيمة، وبالتالي كود الخروج الخاص بـ Perl.

الهدف هو حشر أكبر قدر ممكن من المعلومات حول السبب المحتمل في المساحة المحدودة لكود خروج النظام. ومع ذلك، بما أن $! هي قيمة "errno" الخاصة بلغة C، والتي يمكن ضبطها بواسطة أي استدعاء نظام، فإن هذا يعني أن قيمة كود الخروج المستخدم بواسطة "die" يمكن أن تكون غير متوقعة، لذا لا ينبغي الاعتماد عليها، بخلاف كونها غير صفرية.

يمكنك ترتيب تشغيل استدعاء راجع (callback) قبل أن تقوم "die" بفعلتها، وذلك بضبط خطاف $SIG{__DIE__}. يُستدعى المعالج المرتبط مع الاستثناء كمعطى، ويمكنه تغيير الاستثناء، إذا رأى ذلك مناسباً، عن طريق استدعاء "die" مرة أخرى. انظر "%SIG" في perlvar للحصول على تفاصيل حول ضبط إدخالات %SIG، و "eval" لبعض الأمثلة. على الرغم من أن هذه الميزة كان من المفترض تشغيلها فقط قبل خروج برنامجك مباشرة، إلا أن الأمر ليس كذلك حالياً: يتم استدعاء خطاف $SIG{__DIE__} حالياً حتى داخل الكتل/السلاسل المعالجة بواسطة "eval"! إذا أراد المرء ألا يفعل الخطاف شيئاً في مثل هذه الحالات، فليضع

    die @_ if $^S;
    

كأول سطر في المعالج (انظر "$^S" في perlvar). ولأن هذا يشجع على حدوث أفعال غريبة عن بُعد، فقد يُصلح هذا السلوك غير المتوقع في إصدار مستقبلي.

انظر أيضاً "exit"، و "warn"، ووحدة Carp.

ليست دالة في الواقع. تعيد قيمة آخر أمر في تسلسل الأوامر المشار إليها بواسطة BLOCK. عندما تُعدل بواسطة معدل الحلقة "while" أو "until"، فإنها تنفذ الـ BLOCK مرة واحدة قبل اختبار حالة الحلقة. (في العبارات الأخرى، تختبر معدلات الحلقة الشرط أولاً).

لا تُعتبر "do BLOCK" حلقة، لذا لا يمكن استخدام عبارات التحكم في الحلقة "next"، أو "last"، أو "redo" لمغادرة الكتلة أو إعادة تشغيلها. انظر perlsyn لاستراتيجيات بديلة.

تستخدم قيمة EXPR كاسم ملف وتنفذ محتويات الملف كسكربت Perl:

    # load the exact specified file (./ and ../ special-cased)
    do '/foo/stat.pl';
    do './stat.pl';
    do '../foo/stat.pl';
    # search for the named file within @INC
    do 'stat.pl';
    do 'foo/stat.pl';
    

"do './stat.pl'" تشبه إلى حد كبير

    eval `cat stat.pl`;
    

إلا أنه أكثر إيجازاً، ولا يشغل أي عمليات خارجية، ويتتبع اسم الملف الحالي لرسائل الخطأ. ويختلف أيضاً في أن الكود المقيم بـ "do FILE" لا يمكنه رؤية المتغيرات المعجمية (lexicals) في النطاق المحيط؛ بينما تفعل "eval STRING" ذلك. ومع ذلك، فإنهما يتشابهان في أنه يعيد تحليل الملف في كل مرة تستدعيه فيها، لذا ربما لا ترغب في القيام بذلك داخل حلقة تكرار.

استخدام "do" مع مسار نسبي (باستثناء ./ و ../)، مثل

    do 'foo/stat.pl';
    

سيبحث في أدلة @INC، ويحدث %INC إذا وُجد الملف. انظر "@INC" في perlvar و "%INC" في perlvar لهذه المتغيرات. لاحظ بشكل خاص أنه بينما كانت @@INC تاريخياً تحتوي على '.' (الدليل الحالي) مما يجعل هاتين الحالتين متكافئتين، إلا أن ذلك لم يعد بالضرورة هو الحال، حيث لم يعد '.' مضمناً في @INC مبدئياً في إصدارات perl 5.26.0 فصاعداً. بدلاً من ذلك، سيحذر perl الآن:

    do "stat.pl" failed, '.' is no longer in @INC;
    did you mean do "./stat.pl"?
    

إذا تمكنت "do" من قراءة الملف ولكن لم تتمكن من تصريفه، فإنها تعيد "undef" وتضبط رسالة خطأ في $@. إذا لم تتمكن "do" من قراءة الملف، فإنها تعيد undef وتضبط $! على الخطأ. افحص دائماً $@ أولاً، لأن التصريف قد يفشل بطريقة تضبط أيضاً $!. إذا صُرّف الملف بنجاح، تعيد "do" قيمة آخر تعبير تمت معالجته.

من الأفضل تضمين وحدات المكتبة باستخدام عاملي "use" و "require"، واللذين يقومان أيضاً بفحص تلقائي للأخطاء وإثارة استثناء إذا وُجدت مشكلة.

قد ترغب في استخدام "do" لقراءة ملف تهيئة البرنامج. يمكن إجراء فحص يدوي للأخطاء بهذه الطريقة:

    # Read in config files: system first, then user.
    # Beware of using relative pathnames here.
    for $file ("/share/prog/defaults.rc",
               "$ENV{HOME}/.someprogrc")
    {
        unless ($return = do $file) {
            warn "couldn't parse $file: $@" if $@;
            warn "couldn't do $file: $!"    unless defined $return;
            warn "couldn't run $file"       unless $return;
        }
    }
    
dump LABEL
dump EXPR
تؤدي هذه الدالة إلى تفريغ الذاكرة (core dump) فوراً. انظر أيضاً مفتاح سطر الأوامر -u في perlrun، الذي يفعل الشيء نفسه. القصد الرئيس من ذلك هو أن تتمكن من استخدام برنامج undump (غير مرفق) لتحويل تفريغ الذاكرة إلى ملف ثنائي قابل للتنفيذ بعد تهيئة جميع متغيراتك في بداية البرنامج. عندما يُنفذ الملف الثنائي الجديد، سيبدأ بتنفيذ "goto LABEL" (مع جميع القيود التي تعاني منها "goto"). فكر في الأمر على أنه goto مع تفريغ ذاكرة وتقمص (reincarnation) متدخلين. إذا حُذف الـ "LABEL"، فسيُعاد تشغيل البرنامج من البداية. يسمح شكل "dump EXPR"، المتاح بدءاً من الإصدار 5.18.0 من Perl، بحساب اسم في وقت التشغيل، وهو مطابق لـ "dump LABEL" فيما عدا ذلك.

تحذير: أي ملفات كانت مفتوحة في وقت التفريغ لن تظل مفتوحة عندما يُتقمص البرنامج، مما قد يؤدي إلى ارتباك في Perl.

هذه الدالة مهجورة الآن إلى حد كبير، ويرجع ذلك غالباً إلى صعوبة تحويل ملف core إلى ملف تنفيذي. بدءاً من Perl 5.30، يجب استدعاؤها كـ CORE::dump().

على عكس معظم العوامل المسماة، فإن لهذا العامل نفس أسبقية الإسناد. وهو معفى أيضاً من قاعدة "يبدو وكأنه دالة"، لذا فإن "dump ("foo")."bar"" ستجعل "bar" جزءاً من المعطى لـ "dump".

قضايا النقل: "dump" في perlport.

عند استدعائها على مصفوفة مبعثرة في سياق القائمة، تعيد قائمة من عنصرين تتكون من المفتاح والقيمة للعنصر التالي في المصفوفة. وعند استدعائها في سياق سلمي، تعيد المفتاح فقط (وليس القيمة).

عند استدعائها على مصفوفة في سياق القائمة، في Perl 5.12 وما بعده، فإنها تعيد قائمة من عنصرين تتكون من الفهرس والقيمة للعنصر التالي في المصفوفة حتى تتمكن من تكرارها؛ تعتبر إصدارات Perl الأقدم هذا خطأً في الصيغة. وعند استدعائها في سياق سلمي، تعيد الفهرس في المصفوفة فقط.

تُعاد مدخلات المصفوفة المبعثرة بترتيب يبدو عشوائياً. الترتيب العشوائي الفعلي هو خاص بمصفوفة معينة؛ وقد تؤدي نفس السلسلة بالضبط من العمليات على مصفوفتين مبعثرتين إلى ترتيب مختلف لكل منهما. أي عملية إدراج في المصفوفة قد تغير الترتيب، وكذلك أي حذف، باستثناء أنه يمكن حذف أحدث مفتاح أعيد بواسطة "each" أو "keys" دون تغيير الترتيب. طالما أن مصفوفة معينة لم تُعدل، يمكنك الاعتماد على "keys" و "values" و "each" لإعادة نفس الترتيب بشكل متكرر كما هو الحال مع بعضها البعض. انظر "Algorithmic Complexity Attacks" في perlsec للحصول على تفاصيل حول سبب عشوائية ترتيب المصفوفات المبعثرة. بصرف النظر عن الضمانات المقدمة هنا، فإن التفاصيل الدقيقة لخوارزمية مصفوفات Perl المبعثرة وترتيب اجتيازها عرضة للتغيير في أي إصدار من Perl.

تُعاد مدخلات المصفوفة من أدنى فهرس أولاً.

 my @colors = (qw(red, green, blue));
 while (my ($index, $value) = each @colors) {
     print "[$index] = $value\n";
 }
 [0] = red
 [1] = green
 [2] = blue
    

بعد أن تعيد "each" جميع المدخلات من المصفوفة المبعثرة أو المصفوفة، يعيد الاستدعاء التالي لـ "each" قائمة فارغة في سياق القائمة و "undef" في السياق السلمي؛ الاستدعاء التالي لذلك يعيد تشغيل التكرار. لكل مصفوفة مبعثرة أو مصفوفة مكرر داخلي خاص بها، يتم الوصول إليه بواسطة "each" و "keys" و "values". يتم إعادة ضبط المكرر ضمناً عندما تصل "each" إلى النهاية كما هو موصوف للتو؛ ويمكن إعادة ضبطه صراحة باستدعاء "keys" أو "values" على المصفوفة المبعثرة أو المصفوفة، أو بالإشارة إلى المصفوفة المبعثرة (ولكن ليس المصفوفة) في سياق القائمة. إذا أضفت أو حذفت عناصر مصفوفة مبعثرة أثناء تكرارها، فإن التأثير على المكرر غير محدد؛ على سبيل المثال، قد يتم تخطي مدخلات أو تكرارها - لذا لا تفعل ذلك. استثناء: من الآمن دائماً حذف البند الذي أعيد مؤخراً بواسطة "each"، لذا يعمل الكود التالي بشكل صحيح:

    while (my ($key, $value) = each %hash) {
        print $key, "\n";
        delete $hash{$key};   # This is safe
    }
    

قد يكون للمصفوفات المبعثرة المرتبطة (Tied hashes) سلوك ترتيب مختلف عن تنفيذ مصفوفات Perl المبعثرة.

المكرر المستخدم بواسطة "each" ملحق بالمصفوفة المبعثرة أو المصفوفة، وهو مشترك بين جميع عمليات التكرار المطبقة على نفس المصفوفة المبعثرة أو المصفوفة. وبالتالي فإن جميع استخدامات "each" على مصفوفة مبعثرة أو مصفوفة معينة تقدم نفس موقع المكرر. جميع استخدامات "each" عرضة أيضاً لإعادة ضبط المكرر بواسطة أي استخدام لـ "keys" أو "values" على نفس المصفوفة المبعثرة أو المصفوفة، أو عن طريق الإشارة إلى المصفوفة المبعثرة (وليس المصفوفة) في سياق القائمة. وهذا يجعل الحلقات القائمة على "each" هشة للغاية: فمن السهل الوصول إلى مثل هذه الحلقة والمكرر قد قطع بالفعل جزءاً من الكائن، أو تخريب حالة المكرر بطريق الخطأ أثناء تنفيذ جسم الحلقة. من السهل جداً إعادة ضبط المكرر صراحة قبل بدء الحلقة، ولكن لا توجد طريقة لعزل حالة المكرر المستخدمة بواسطة حلقة عن حالة المكرر المستخدمة بواسطة أي شيء آخر قد يتم تنفيذه أثناء جسم الحلقة.

يمتد هذا إلى استخدام "each" على نتيجة منشئ هاش أو مصفوفة مجهول. تُنشأ مصفوفة أو هاش أساسي جديد في كل مرة بحيث تبدأ each دائماً التكرار من الصفر، على سبيل المثال:

  # حلقة تكرار للأبد
  while (my ($key, $value) = each %{ +{ a => 1 } }) {
      print "$key=$value\n";
  }
    

لتجنب هذه المشكلات الناتجة عن المكرر المضمن في المفروم (hash-embedded iterator)، استخدم حلقة "foreach" بدلاً من "while"-"each". بدءًا من بيرل 5.36، يمكنك التكرار على كل من المفاتيح والقيم مباشرة باستخدام حلقة "foreach" متعددة القيم.

  # يسترجع المفاتيح مرة واحدة للتكرار
  # لا يتأثر التكرار بأي عمليات على %hash بداخله
  foreach my $key (keys %hash) {
      my $value = $hash{$key};
      $hash{$key} = {keys => scalar keys %hash, outer => [%hash]};
      some_function_that_may_mess_with(\%hash, $key, $value);
      $hash{"new$key"} = delete $hash{$key};
  }
  # بيرل 5.36+
  foreach my ($key, $value) (%{ +{ a => 1 } }) {
      print "$key=$value\n";
  }
    

يقوم هذا بطباعة بيئتك مثل برنامج printenv(1)، ولكن بترتيب مختلف:

    while (my ($key,$value) = each %ENV) {
        print "$key=$value\n";
    }
    

بدءاً من الإصدار 5.14 من Perl، سمحت ميزة تجريبية لـ "each" بأخذ تعبير سلمي. اعتُبرت هذه التجربة غير ناجحة، وأزيلت اعتباراً من الإصدار 5.24 من Perl.

بدءًا من بيرل 5.18، يمكنك استخدام "each" مجردة في حلقة "while"، والتي ستضبط قيمة $_ في كل تكرار. إذا استُخدم تعبير "each" أو تعيين صريح لتعبير "each" إلى قيمة سلمية كشرط "while"/"for"، فإن الشرط يختبر في الواقع كون قيمة التعبير معرفة، وليس قيمتها المنطقية المعتادة.

    while (each %ENV) {
        print "$_=$ENV{$_}\n";
    }
    

لتجنب إرباك المستخدمين المحتملين لكودك الذين يشغلون إصدارات أقدم من Perl بأخطاء صياغة غامضة، ضع هذا النوع من الأشياء في أعلى ملفك للإشارة إلى أن كودك سيعمل فقط على إصدارات Perl الحديثة:

    use v5.12;  # so keys/values/each work on arrays
    use v5.18;  # so each assigns to $_ in a lone while test
    

انظر أيضاً "keys"، و "values"، و "sort".

eof FILEHANDLE
eof ()
يعيد 1 إذا كانت القراءة التالية على FILEHANDLE ستعيد نهاية الملف أو إذا كان FILEHANDLE غير مفتوح. قد يكون FILEHANDLE تعبيراً تعطي قيمته مقبض الملف الحقيقي. (لاحظ أن هذه الدالة تقرأ محرفاً بالفعل ثم تقوم بعملية "ungetc" له، لذا فهي ليست مفيدة في سياق تفاعلي.) لا تقرأ من ملف طرفية (أو تستدعِ eof(FILEHANDLE) عليه) بعد الوصول إلى نهاية الملف. قد تفقد أنواع الملفات مثل الطرفيات حالة نهاية الملف إذا فعلت ذلك.

تستخدم دالة "eof" بدون وسيط آخر ملف قُرئ. استخدام eof() مع قوسين فارغين يختلف؛ إذ يشير إلى الملف الوهمي المكون من الملفات المدرجة في سطر الأوامر والتي يتم الوصول إليها عبر عامل "<>". بما أن "<>" لم يُفتح صراحةً، كما هو حال مقبض الملف العادي، فإن استدعاء eof() قبل استخدام "<>" سيؤدي إلى فحص @ARGV لتحديد ما إذا كان هناك مدخلات متاحة. وبالمثل، فإن استدعاء eof() بعد أن يعيد "<>" نهاية الملف سيفترض أنك تعالج قائمة @ARGV أخرى، وإذا لم تكن قد ضبطت @ARGV، فسيقرأ المدخلات من "STDIN"؛ انظر "I/O Operators" في perlop.

في حلقة "while (<>)"، يمكن استخدام "eof" أو eof(ARGV) لاكتشاف نهاية كل ملف، بينما ستكتشف eof() نهاية الملف الأخير فقط. أمثلة:

    # reset line numbering on each input file
    while (<>) {
        next if /^\s*#/;  # skip comments
        print "$.\t$_";
    } continue {
        close ARGV if eof;  # Not eof()!
    }
    # insert dashes just before last line of last file
    while (<>) {
        if (eof()) {  # check for end of last file
            print "--------------\n";
        }
        print;
        last if eof();     # needed if we're reading from a terminal
    }
    

تلميح عملي: لا تحتاج تقريباً أبداً إلى استخدام "eof" في Perl، لأن عوامل الإدخال عادةً ما تعيد "undef" عندما تنفد البيانات أو تواجه خطأ.

eval EXPR
eval BLOCK
تُستخدم "eval" بجميع أشكالها لتنفيذ برنامج بيرل صغير، مع صيد أي أخطاء تواجَه حتى لا يتوقف البرنامج المستدعِي.

إن استخدام "eval" المجردة بلا معطيات هو مجرد "eval EXPR"، حيث يُفهم أن التعبير محتوى في $_. وبذلك لا يوجد سوى شكلين حقيقيين لـ "eval"؛ يُسمى الشكل الذي يحتوي على EXPR غالباً "string eval". في تقييم السلسلة النصية، تُحلل قيمة التعبير (التي تُحدد ضمن سياق سلمي) أولاً، وإذا لم توجد أخطاء، تُنفذ ككتلة برمجية داخل السياق المفرداتي لبرنامج بيرل الحالي. يُستخدم هذا الشكل عادةً لتأخير التحليل والتنفيذ اللاحق لنص EXPR حتى وقت التشغيل. لاحظ أن القيمة تُحلل في كل مرة تُنفذ فيها "eval".

يُسمى الشكل الآخر "block eval". وهو أقل عمومية من تقييم السلسلة، لكن الشيفرة داخل BLOCK تُحلل مرة واحدة فقط (في نفس الوقت الذي حُللت فيه الشيفرة المحيطة بـ "eval" نفسها) وتُنفذ داخل سياق برنامج بيرل الحالي. يُستخدم هذا الشكل عادةً لصيد الاستثناءات بكفاءة أكبر من الأول، مع توفير ميزة التحقق من الشيفرة داخل BLOCK في وقت التصريف. تُحلل BLOCK وتُصرف مرة واحدة فقط. وبما أن الأخطاء تُصاد، فغالباً ما تُستخدم للتحقق مما إذا كانت ميزة معينة متاحة.

في كلا الشكلين، تكون القيمة المعادة هي قيمة آخر تعبير قُيم داخل البرنامج الصغير؛ ويمكن أيضاً استخدام جملة return، تماماً كما في الدوال الفرعية. يُقيم التعبير الذي يقدم القيمة المعادة في سياق فارغ، أو سلمي، أو قائمة، اعتماداً على سياق "eval" نفسها. راجع "wantarray" للمزيد حول كيفية تحديد سياق التقييم.

إذا وجد خطأ في بناء الجملة أو خطأ في وقت التشغيل، أو نُفذت جملة "die"، تعيد "eval" القيمة "undef" في السياق السلمي، أو قائمة فارغة في سياق القائمة، وتُضبط $@ على رسالة الخطأ. (قبل الإصدار 5.16، تسبب خطأ برمجبي في إعادة "undef" في سياق القائمة لأخطاء بناء الجملة، وليس لأخطاء وقت التشغيل). إذا لم يوجد خطأ، تُضبط $@ على سلسلة فارغة. يمكن لعامل التحكم في التدفق مثل "last" أو "goto" تجاوز ضبط $@. احذر من أن استخدام "eval" لا يمنع بيرل من طباعة التحذيرات إلى STDERR، ولا يضع نص رسائل التحذير داخل $@. للقيام بأي منهما، يجب استخدام مرفق $SIG{__WARN__}، أو إيقاف التحذيرات داخل BLOCK أو EXPR باستخدام "no warnings 'all'". راجع "warn" و perlvar و warnings.

لاحظ أنه نظراً لأن "eval" تصيد الأخطاء التي قد تكون قاتلة لولاها، فهي مفيدة لتحديد ما إذا كانت ميزة معينة (مثل "socket" أو "symlink") مُنفذة. كما أنها آلية بيرل لصيد الاستثناءات، حيث يُستخدم عامل "die" لرفع الاستثناءات.

قبل الإصدار 5.14 من بيرل، كان التعيين لـ $@ يحدث قبل استعادة المتغيرات المحلية، مما يعني أنه لكي تعمل شيفرتك على الإصدارات القديمة، يلزم وجود متغير مؤقت إذا كنت تريد إخفاء بعض الأخطاء وليس كلها:

 # عدل $@ في حالة التنافر الشنيع فقط
 {
    my $e;
    {
      local $@; # احمِ $@ الموجودة
      eval { test_repugnancy() };
      # $@ =~ /nefarious/ and die $@; # لبيرل 5.14 وأعلى فقط
      $@ =~ /nefarious/ and $e = $@;
    }
    die $e if defined $e
 }
    

توجد اعتبارات مختلفة لكل شكل:

تقييم السلسلة (String eval)
بما أن القيمة المعادة من EXPR تُنفذ ككتلة داخل السياق المفرداتي لبرنامج بيرل الحالي، فإن أي متغيرات مفرداتية خارجية تكون مرئية لها، وأي إعدادات لمتغيرات الحزمة أو تعريفات الدوال الفرعية والتنسيقات تبقى قائمة بعدها.

لاحظ أنه عند تضمين كتل "BEGIN {}" داخل كتلة eval، فإن محتويات الكتلة ستُنفذ فوراً وقبل تنفيذ بقية شيفرة eval. يمكنك تعطيل هذا تماماً عن طريق

   local ${^MAX_NESTED_EVAL_BEGIN_BLOCKS} = 0;
   eval $string;
    

مما سيؤدي إلى رمي أي كتل "BEGIN" مضمنة في $string لاستثناء.

إذا مُكنت هذه الميزة (وهو المبدئي تحت إعلان "use 5.16" أو أعلى)، تفترض بيرل أن EXPR هي سلسلة محارف. وبذلك لا يكون لأي إعلانات "use utf8" أو "no utf8" داخل السلسلة أي أثر. كما تمنع مرشحات المصدر أيضاً. (ومع ذلك، يمكن لـ "unicode_strings" الظهور داخل السلسلة).

راجع أيضاً عامل "evalbytes"، الذي يعمل بشكل صحيح مع مرشحات المصدر.

في هذه الحالة، يكون السلوك إشكالياً ولا يمكن وصفه بسهولة. إليك خطأين برمجيين لا يمكن إصلاحهما بسهولة دون كسر البرامج الموجودة:
يؤثر تخزين بيرل الداخلي لـ EXPR على سلوك الكود المُنفذ. على سبيل المثال:

    my $v = eval "use utf8; '$expr'";
    

إذا كانت $expr هي "\xc4\x80" (أي U+0100 في UTF-8)، فإن القيمة المخزنة في $v ستعتمد على ما إذا كانت بيرل تخزن $expr بوضع "الترقية" (راجع utf8) أم لا:

  • إذا رُقيت، ستكون $v هي "\xc4\x80" (أي أن "use utf8" ليس له أثر).
  • إذا لم تُرَقَّ، ستكون $v هي "\x{100}".

هذا غير مرغوب فيه لأن الترقية من عدمها يجب ألا تؤثر على سلوك السلسلة النصية.

تتسرب مرشحات المصدر المفعلة داخل "eval" إلى أي نطاق ملف يُصرف حالياً. لإعطاء مثال مع وحدة CPAN المسماة Semi::Semicolons:

 BEGIN { eval "use Semi::Semicolons; # لا يرشح هنا" }
 # يرشح هنا!
    

تصلح "evalbytes" ذلك لتعمل بالطريقة المتوقعة:

 use feature "evalbytes";
 BEGIN { evalbytes "use Semi::Semicolons; # مرشح" }
 # غير مرشح
    

قد تظهر مشكلات إذا وسعت السلسلة النصية متغيراً سلمياً يحتوي على رقم بفاصلة عائمة. يمكن لهذا السلمي أن يتوسع إلى أحرف، مثل "NaN" أو "Infinity"؛ أو، داخل نطاق "use locale"، قد يكون محرف الفاصلة العشرية شيئاً آخر غير النقطة (مثل الفاصلة). من غير المرجح أن يُحلل أي من هذه الحالات كما تتوقع.

يجب أن تكون حذراً بشكل خاص لتذكر ما الذي يُنظر إليه عندما:

    eval $x;        # الحالة 1
    eval "$x";      # الحالة 2
    eval '$x';      # الحالة 3
    eval { $x };    # الحالة 4
    eval "\$$x++";  # الحالة 5
    $$x++;          # الحالة 6

تعمل الحالتان 1 و 2 أعلاه بشكل متطابق: فهما تشغلان الشيفرة الموجودة في المتغير $x. (رغم أن الحالة 2 تحتوي على علامات اقتباس مزدوجة مضللة تجل القارئ يتساءل عما قد يحدث أيضاً (لا شيء يحدث)). وبالمثل، تعمل الحالتان 3 و 4 بنفس الطريقة: فهما تشغلان الشيفرة '$x'، والتي لا تفعل شيئاً سوى إعادة قيمة $x. (تُفضل الحالة 4 لأسباب بصرية بحتة، ولكن لها أيضاً ميزة التصريف في وقت التصريف بدلاً من وقت التشغيل). الحالة 5 هي مكان قد ترغب فيه عادةً باستخدام علامات الاقتباس المزدوجة، باستثناء أنه في هذه الحالة بالذات، يمكنك فقط استخدام المراجع الرمزية بدلاً من ذلك، كما في الحالة 6.

إن "eval ''" التي تُنفذ داخل روتين فرعي مُعرف في حزمة "DB" لا ترى النطاق المعجمي (lexical scope) المحيط المعتاد، بل نطاق أول قطعة كود ليست من حزمة DB استدعتها. عادةً لا تحتاج للقلق بشأن هذا إلا إذا كنت تكتب منقح بيرل.

يمكن حذف الفاصلة المنقوطة النهائية، إن وجدت، من قيمة EXPR.

تقييم الكتلة (Block eval)
إذا كان الكود المراد تنفيذه لا يتغير، يمكنك استخدام شكل eval-BLOCK لصيد أخطاء وقت التشغيل دون تحمل تكلفة إعادة التصريف في كل مرة. يُعاد الخطأ، إن وجد، في $@. أمثلة:

    # اجعل القسمة على صفر غير قاتلة
    eval { $answer = $x / $y; }; warn $@ if $@;
    # نفس الشيء، ولكن بكفاءة أقل
    eval '$answer = $x / $y'; warn $@ if $@;
    # خطأ في وقت التصريف
    eval { $answer = }; # خطأ
    # خطأ في وقت التشغيل
    eval '$answer =';   # تضبط $@
    

إذا كنت تريد صيد الأخطاء عند تحميل وحدة XS، فقد تكون بعض المشكلات في الواجهة الثنائية (مثل تضارب إصدارات بيرل) قاتلة حتى مع استخدام "eval" ما لم يُضبط $ENV{PERL_DL_NONLAZY}. راجع perlrun.

إن استخدام شكل "eval {}" كمصيدة استثناءات في المكتبات له بعض المشكلات. نظراً للحالة المعطلة حالياً لخطافات "__DIE__"، قد ترغب في عدم إطلاق أي خطافات "__DIE__" قد تكون شيفرة المستخدم قد ثبتتها. يمكنك استخدام بنية "local $SIG{__DIE__}" لهذا الغرض، كما يوضح هذا المثال:

    # مصيدة استثناء خاصة للقسمة على صفر
    eval { local $SIG{'__DIE__'}; $answer = $x / $y; };
    warn $@ if $@;
    

هذا مهم بشكل خاص، نظراً لأن خطافات "__DIE__" يمكنها استدعاء "die" مرة أخرى، مما يؤدي إلى تغيير رسائل الخطأ الخاصة بها:

    # قد تعدل خطافات __DIE__ رسائل الخطأ
    {
       local $SIG{'__DIE__'} =
              sub { (my $x = $_[0]) =~ s/foo/bar/g; die $x };
       eval { die "foo lives here" };
       print $@ if $@;                # تطبع "bar lives here"
    }
    

لأن هذا يشجع على التأثير عن بعد، فقد يُصلح هذا السلوك غير المتوقع في إصدار مستقبلي.

لا تُعتبر "eval BLOCK" حلقة تكرار، لذا لا يمكن استخدام جمل التحكم في الحلقات "next" أو "last" أو "redo" لمغادرة الكتلة أو إعادة تشغيلها.

يمكن حذف الفاصلة المنقوطة النهائية، إن وجدت، من داخل BLOCK.

evalbytes EXPR
هذه الدالة تشبه تقييم السلسلة، إلا أنها تحلل معطاها دائماً (أو $_ إذا حُذفت EXPR) كسلسلة بايتات. إذا احتوت السلسلة على أي نقاط ترميز فوق 255، فلا يمكن أن تكون سلسلة بايتات، وستفشل "evalbytes" مع تخزين الخطأ في $@.

يكون لـ "use utf8" و "no utf8" داخل السلسلة أثرهما المعتاد.

تنطبق مرشحات المصدر المفعلة داخل الشيفرة المقيمة على الشيفرة نفسها.

تتوفر "evalbytes" بدءاً من الإصدار 5.16 من بيرل. للوصول إليها، يجب كتابة "CORE::evalbytes"، ولكن يمكنك حذف "CORE::" إذا كانت ميزة "evalbytes" مُمكّنة. تُمكّن هذه الميزة آلياً عند استخدام إعلان "use v5.16" (أو أعلى) في النطاق الحالي.

تنفذ دالة "exec" أمراً للنظام ولا تعود أبداً؛ استخدم "system" بدلاً من "exec" إذا أردت منها أن تعود. تفشل وتُعيد خطأ فقط إذا كان الأمر غير موجود و نُفذت مباشرة بدلاً من تنفيذها عبر صدفة أوامر نظامك (انظر أدناه).

بما أنه من الخطأ الشائع استخدام "exec" بدلاً من "system"، فإن بيرل يحذرك إذا استُدعيت "exec" في سياق فارغ (void context) وإذا كانت هناك جملة تالية ليست "die" أو "warn" أو "exit" (إذا كانت التحذيرات مفعلة -- لكنك تفعل ذلك دائماً، أليس كذلك؟). إذا كنت حقاً تريد اتباع "exec" بجملة أخرى، يمكنك استخدام أحد هذه الأنماط لتجنب التحذير:

    exec ('foo')   أو print STDERR "تعذر exec foo: $!";
    { exec ('foo') }; print STDERR "تعذر exec foo: $!";
    

إذا كان هناك أكثر من وسيط في LIST، فإن هذا يستدعي execvp(3) بالوسائط الموجودة في LIST. إذا كان هناك عنصر واحد فقط في LIST، يُفحص الوسيط بحثاً عن محارف الصدفة الوصفية (shell metacharacters)، وإذا وُجد أي منها، يُمرر الوسيط بالكامل إلى صدفة أوامر النظام لتحليله (هذا هو "/bin/sh -c" على منصات يونكس، ولكنه يختلف في المنصات الأخرى). إذا لم تكن هناك محارف صدفة وصفية في الوسيط، يُقسم إلى كلمات ويُمرر مباشرة إلى "execvp"، وهو أكثر كفاءة. أمثلة:

    exec '/bin/echo', 'Your arguments are: ', @ARGV;
    exec "sort $outfile | uniq";
    

إذا كنت لا تريد حقاً تنفيذ الوسيط الأول، ولكن تريد أن تكذب على البرنامج الذي تنفذه بشأن اسمه، يمكنك تحديد البرنامج الذي تريد تشغيله بالفعل كـ "كائن غير مباشر" (بدون فاصلة) أمام LIST، كما في "exec PROGRAM LIST". (يفرض هذا دائماً تفسير LIST كقائمة متعددة القيم، حتى لو كان هناك قيمة سلمية واحدة فقط في القائمة.) مثال:

    my $shell = '/bin/csh';
    exec $shell '-sh';    # تظاهر بأنها صدفة ولوج
    

أو، بشكل مباشر أكثر،

    exec {'/bin/csh'} '-sh';  # تظاهر بأنها صدفة ولوج
    

عندما تُنفذ الوسائط عبر صدفة النظام، تخضع النتائج لتقلباتها وقدراتها. انظر "`STRING`" في perlop لمزيد من التفاصيل.

استخدام كائن غير مباشر مع "exec" أو "system" هو أيضاً أكثر أماناً. هذا الاستخدام (الذي يعمل بشكل جيد أيضاً مع "system") يفرض تفسير الوسائط كقائمة متعددة القيم، حتى لو كانت القائمة تحتوي على وسيط واحد فقط. بهذه الطريقة تكون آمناً من قيام الصدفة بتوسيع الأحرف البديلة (wildcards) أو تقسيم الكلمات التي تحتوي على مسافات بيضاء.

    my @args = ( "echo surprise" );
    exec @args;               # عرضة لهروب الصدفة
                                # إذا كانت @args == 1
    exec { $args[0] } @args;  # آمنة حتى مع قائمة من معطى واحد
    

النسخة الأولى، تلك التي بدون كائن غير مباشر، شغلت برنامج echo، ومررت له "surprise" كوسيط. النسخة الثانية لم تفعل ذلك؛ بل حاولت تشغيل برنامج يسمى "echo surprise"، ولم تجده، وضبطت $? على قيمة غير صفرية تشير إلى الفشل.

في ويندوز، وحدها صيغة الكائن غير مباشر "exec PROGRAM LIST" تتجنب استخدام الصدفة بشكل موثوق؛ أما "exec LIST"، حتى مع أكثر من عنصر، فستعود إلى الصدفة إذا فشل التشغيل الأول.

تحاول بيرل إفراغ جميع الملفات المفتوحة للمخرجات قبل تنفيذ exec، ولكن قد لا يكون هذا مدعوماً في بعض المنصات (راجع perlport). لكي تكون آمناً، قد تحتاج لضبط $| (أو $AUTOFLUSH بالإنجليزية) أو استدعاء طريقة "autoflush" الخاصة بـ "IO::Handle" على أي مقابض مفتوحة لتجنب فقدان المخرجات.

لاحظ أن "exec" لن تستدعي كتل "END" الخاصة بك، ولن تستدعي طرق "DESTROY" على كائناتك.

قضايا النقلية: "exec" في perlport.

عند إعطائها تعبيراً يحدد عنصراً في مفرمة (hash)، تعيد قيمة صحيحة إذا سبق تهيئة العنصر المحدد في المفرمة، حتى لو كانت القيمة المقابلة غير معرفة.

    print "Exists\n"    if exists $hash{$key};
    print "Defined\n"   if defined $hash{$key};
    print "True\n"      if $hash{$key};
    

يمكن أيضاً استدعاء exists على عناصر المصفوفة، لكن سلوكها أقل وضوحاً بكثير ويرتبط بقوة باستخدام "delete" على المصفوفات.

تحذير: لا يُنصح بشدة باستدعاء "exists" على قيم المصفوفة. إن فكرة حذف أو التحقق من وجود عناصر مصفوفة بيرل ليست متماسكة مفاهيمياً، ويمكن أن تؤدي إلى سلوك مفاجئ.

    print "Exists\n"    if exists $array[$index];
    print "Defined\n"   if defined $array[$index];
    print "True\n"      if $array[$index];
    

يمكن لعنصر في مفروم أو مصفوفة أن يكون صحيحاً (true) فقط إذا كان معرفاً، ويكون معرفاً فقط إذا كان موجوداً، ولكن العكس ليس بالضرورة صحيحاً.

عند إعطائها تعبيراً يحدد اسم دالة فرعية، تعيد قيمة صحيحة إذا سبق التصريح عن الدالة الفرعية المحددة، حتى لو كانت غير معرفة. ذكر اسم دالة فرعية من أجل exists أو defined لا يُعد تصريحاً عنها. لاحظ أن الدالة الفرعية التي لا توجد قد تظل قابلة للاستدعاء: فقد تحتوي حزمتها على طريقة "AUTOLOAD" تجعلها تظهر للوجود في أول مرة تُستدعى فيها؛ راجع perlsub.

    print "Exists\n"  if exists &subroutine;
    print "Defined\n" if defined &subroutine;
    

لاحظ أن EXPR يمكن أن تكون معقدة بشكل اختياري طالما أن العملية النهائية هي بحث عن مفتاح مفرمة أو مصفوفة أو اسم دالة فرعية:

    if (exists $ref->{A}->{B}->{$key})  { }
    if (exists $hash{A}{B}{$key})       { }
    if (exists $ref->{A}->{B}->[$ix])   { }
    if (exists $hash{A}{B}[$ix])        { }
    if (exists &{$ref->{A}{B}{$key}})   { }
    

رغم أن عنصر المصفوفة أو المفرمة الأكثر عمقاً لن يظهر للوجود لمجرد اختبار وجوده، إلا أن أي عناصر متوسطة ستظهر. وبذلك سيظهر "$ref->{"A"}" و "$ref->{"A"}->{"B"}" إلى الوجود بسبب اختبار الوجود لعنصر $key أعلاه. يحدث هذا في أي مكان يُستخدم فيه عامل السهم، بما في ذلك هنا:

    undef $ref;
    if (exists $ref->{"Some key"})    { }
    print $ref;  # تطبع HASH(0x80d3d5c)
    

إن استخدام استدعاء دالة فرعية، بدلاً من اسم الدالة الفرعية، كمعطى لـ "exists" يعد خطأ.

    exists &sub;    # مقبول
    exists &sub();  # خطأ
    
exit EXPR
تقيم EXPR وتخرج فوراً بتلك القيمة. مثال:

    my $ans = <STDIN>;
    exit 0 if $ans =~ /^[Xx]/;
    

انظر أيضاً "die". إذا أُغفل EXPR، يخرج بالحالة 0. القيم الوحيدة المعترف بها عالمياً لـ EXPR هي 0 للنجاح و 1 للخطأ؛ القيم الأخرى تخضع للتفسير اعتماداً على البيئة التي يعمل فيها برنامج بيرل. على سبيل المثال، الخروج بالقيمة 69 (EX_UNAVAILABLE) من مرشح بريد وارد لـ sendmail سيجعل برنامج البريد يعيد الرسالة غير مسلمة، لكن هذا ليس صحيحاً في كل مكان.

لا تستخدم "exit" لإنهاء روتين فرعي إذا كان هناك أي احتمال أن شخصاً ما قد يرغب في صيد أي خطأ حدث. استخدم "die" بدلاً من ذلك، والتي يمكن صيدها بواسطة "eval".

لا تخرج دالة "exit" دائماً فوراً. فهي تستدعي أي روتينات "END" معرفة أولاً، ولكن روتينات "END" هذه قد لا تحبط الخروج بنفسها. وبالمثل، تُستدعى أي مدمرات كائنات يلزم استدعاؤها قبل الخروج الفعلي. يمكن لروتينات "END" والمدمرات تغيير حالة الخروج بتعديل $?. إذا كان هذا يشكل مشكلة، يمكنك استدعاء POSIX::_exit($status) لتجنب معالجة "END" والمدمرات. راجع perlmod للتفاصيل.

قضايا النقلية: "exit" في perlport.

exp EXPR
تعيد e (أساس اللوغاريتم الطبيعي) مرفوعاً للقوة EXPR. إذا حُذفت EXPR، تعطي exp($_).
fc EXPR
تعيد نسخة "مطوية الحالة" (casefolded) من EXPR. هذه هي الدالة الداخلية التي تطبق هروب "\F" في السلاسل النصية ذات الاقتباس المزدوج.

طي الحالة هو عملية تعيين السلاسل النصية إلى شكل تُمحى فيه فروق حالة الأحرف؛ ومقارنة سلسلتين في شكلهما المطوي هو في الواقع وسيلة للتساؤل عما إذا كانت السلسلتان متساويتين بغض النظر عن الحالة.

تقريباً، إذا وجدت نفسك يوماً تكتب هذا

    lc($this) eq lc($that)    # خطأ!
        # أو
    uc($this) eq uc($that)    # خطأ أيضاً!
        # أو
    $this =~ /^\Q$that\E\z/i  # صواب!
    

الآن يمكنك كتابة

    fc($this) eq fc($that)
    

والحصول على نتائج صحيحة.

تطبق بيرل الشكل الكامل لطي الحالة فقط، ولكن يمكنك الوصول إلى الطيات البسيطة باستخدام "casefold()" في Unicode::UCD و "prop_invmap()" في Unicode::UCD. لمزيد من المعلومات حول طي الحالة، ارجع إلى معيار يونيكود، وتحديداً الأقسام 3.13 "Default Case Operations"، و 4.2 "Case-Normative"، و 5.18 "Case Mappings"، المتوفرة في <https://www.unicode.org/versions/latest/>، بالإضافة إلى جداول الحالات المتوفرة في <https://www.unicode.org/charts/case/>.

إذا حُذفت EXPR، تُستخدم $_.

تعمل هذه الدالة بنفس الطريقة تحت توجيهات برمجية مختلفة، مثل "use feature 'unicode_strings"، كما تفعل "lc"، مع استثناء وحيد وهو "fc" لـ LATIN CAPITAL LETTER SHARP S (U+1E9E) ضمن نطاق "use locale". يكون طي حالة هذا المحرف عادةً هو "ss"، ولكن كما شُرح في قسم "lc"، فإن تغييرات الحالة التي تتجاوز الحد 255/256 تكون إشكالية تحت المحليات (locales)، وبالتالي هي محظورة. لذا، تعيد هذه الدالة تحت المحلية بدلاً من ذلك السلسلة "\x{17F}\x{17F}"، وهي محرف LATIN SMALL LETTER LONG S. وبما أن هذا المحرف نفسه يطوى إلى "s"، فإن سلسلة من اثنين منهما معاً يجب أن تكون مكافئة لـ U+1E9E واحدة عند طي حالتها.

بينما يعرف معيار يونيكود شكلين إضافيين لطي الحالة، أحدهما للغات التركية والآخر لا يعين أبداً محرفاً واحداً إلى محارف متعددة، إلا أن نواة بيرل لا توفرهما. ومع ذلك، يمكن استخدام وحدة CPAN المسماة "Unicode::Casing" لتوفير تطبيق لهما.

دالة "fc" متاحة فقط إذا تم تمكين ميزة "fc" أو إذا كانت مسبوقة بـ "CORE::". يتم تمكين ميزة "fc" تلقائيًا عند التصريح عن استخدام "use v5.16" (أو إصدار أحدث) في النطاق الحالي.

تنفذ دالة fcntl(2). ستحتاج على الأرجح لقول

    use Fcntl;
    

أولاً للحصول على تعريفات الثوابت الصحيحة. تعمل معالجة المعطيات والقيمة المعادة تماماً مثل "ioctl" أدناه. على سبيل المثال:

    use Fcntl;
    my $flags = fcntl($filehandle, F_GETFL, 0)
        أو die "تعذر fcntl F_GETFL: $!";
    

ليس عليك التحقق من "defined" عند العودة من "fcntl". مثل "ioctl"، فإنها تخرط قيمة 0 العائدة من نداء النظام إلى "0 but true" في بيرل. هذه السلسلة صحيحة (true) في سياق منطقي و 0 في سياق عددي. كما أنها معفاة من تحذيرات "Argument "..." isn't numeric" المعتادة عند التحويلات العددية غير الصحيحة.

لاحظ أن "fcntl" ترفع استثناءً إذا استُخدمت على آلة لا تنفذ fcntl(2). انظر وحدة Fcntl أو صفحة دليل fcntl(2) لمعرفة الدوال المتاحة على نظامك.

إليك مثال على ضبط مقبض ملف يسمى $REMOTE ليكون غير حاجز (non-blocking) على مستوى النظام. سيتعين عليك التعامل مع $| بنفسك، رغم ذلك.

    use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
    my $flags = fcntl($REMOTE, F_GETFL, 0)
        أو die "تعذر الحصول على الأعلام للمقبس: $!\n";
    fcntl($REMOTE, F_SETFL, $flags | O_NONBLOCK)
        أو die "تعذر ضبط الأعلام للمقبس: $!\n";
    

قضايا النقلية: "fcntl" في perlport.

__FILE__
وسم خاص يعيد اسم الملف الذي يظهر فيه. يمكن تغييره بواسطة الآلية الموصوفة في "Plain Old Comments (Not!)" في perlsyn.
يصرح عن متغير حقل جديد داخل الصنف الحالي. سيكون للطرق وكتل "ADJUST" في الصنف وصول إلى هذا المتغير كما لو كان مفرداتياً في النطاق عند تلك النقطة.
تعيد واصف الملف لمقبض ملف أو مقبض دليل، أو قيمة غير معرفة إذا لم يكن مقبض الملف مفتوحاً. إذا لم يوجد واصف ملف حقيقي على مستوى نظام التشغيل، كما يمكن أن يحدث مع مقابض الملفات المتصلة بكائنات ذاكرة عبر "open" مع مرجع كمعطى ثالث، تُعاد القيمة -1.

هذا مفيد بشكل رئيس لبناء خرائط بت لـ "select" وعمليات معالجة POSIX tty منخفضة المستوى. إذا كان FILEHANDLE تعبيراً، تُؤخذ القيمة كمقبض ملف غير مباشر، وعادة ما تكون اسمه.

يمكنك استخدام هذا لمعرفة ما إذا كان مقبضان يشيران إلى نفس الواصف الكامن:

    if (fileno($this) != -1 && fileno($this) == fileno($that)) {
        print "\$this و \$that متطابقان\n";
    } elsif (fileno($this) != -1 && fileno($that) != -1) {
        print "\$this و \$that لهما " .
            "واصفات ملفات كامنة مختلفة\n";
    } else {
        print "واحد على الأقل من \$this و \$that ليس " .
            "له واصف ملف حقيقي\n";
    }
    

يعتمد سلوك "fileno" على مقبض الدليل على نظام التشغيل. في نظام يحتوي على dirfd(3) أو ما شابه، تعيد "fileno" على مقبض الدليل واصف الملف الكامن المرتبط بالمقبض؛ أما في الأنظمة التي لا توفر هذا الدعم، فتعيد القيمة غير المعرفة وتضبط $! (errno).

تستدعي flock(2)، أو محاكاة لها، على FILEHANDLE. تعيد صحيح (true) للنجاح، وخطأ (false) للفشل. تنتج خطأً قاتلاً إذا استُخدمت على آلة لا تنفذ قفل flock(2) أو fcntl(2)، أو lockf(3). إن "flock" هي واجهة بيرل المنقولة لقفل الملفات، على الرغم من أنها تقفل الملفات الكاملة فقط، وليس السجلات.

هناك دلالتان تقليديتان لـ "flock" قد لا تكونان واضحتين هما أنها تنتظر إلى أجل غير مسمى حتى يُمنح القفل، وأن أقفالها مجرد استشارية (merely advisory). هذه الأقفال التقديرية أكثر مرونة، ولكنها تقدم ضمانات أقل. هذا يعني أن البرامج التي لا تستخدم "flock" أيضاً قد تعدل الملفات المقفولة بـ "flock". انظر perlport، والوثائق الخاصة بمنفذك، وصفحات الدليل المحلية الخاصة بنظامك للحصول على التفاصيل. من الأفضل افتراض السلوك التقليدي إذا كنت تكتب برامج منقولة. (ولكن إذا لم تكن كذلك، فيجب عليك كالعادة أن تشعر بحرية تامة في الكتابة لخصوصيات نظامك (التي تسمى أحياناً "ميزات"). إن التمسك العبودي بمخاوف النقل يجب ألا يقف في طريق إنجاز عملك.)

إن OPERATION هي واحدة من LOCK_SH أو LOCK_EX أو LOCK_UN، وربما مدمجة مع LOCK_NB. هذه الثوابت قيمها تقليدياً هي 1 و 2 و 8 و 4، ولكن يمكنك استخدام الأسماء الرمزية إذا استوردتها من وحدة Fcntl، إما بشكل فردي، أو كمجموعة باستخدام وسم ":flock". يطلب LOCK_SH قفلاً مشتركاً، ويطلب LOCK_EX قفلاً حصرياً، ويحرر LOCK_UN قفلاً طُلب مسبقاً. إذا طُبق عامل 'أو' (bitwise-or) على LOCK_NB مع LOCK_SH أو LOCK_EX، فإن "flock" تعود فوراً بدلاً من الحجز لانتظار القفل؛ تحقق من حالة العودة لمعرفة ما إذا كنت قد حصلت عليه.

لتجنب احتمال عدم التنسيق، تقوم بيرل الآن بإفراغ FILEHANDLE قبل قفله أو إلغاء قفله.

لاحظ أن المحاكاة المبنية بـ lockf(3) لا توفر أقفالاً مشتركة، وتتطلب أن يكون FILEHANDLE مفتوحاً بنية الكتابة. هذه هي الدلالات التي ينفذها lockf(3). معظم الأنظمة إن لم يكن كلها تنفيذ lockf(3) من حيث قفل fcntl(2)، لذا فإن الدلالات المختلفة يجب ألا تضر الكثير من الناس.

لاحظ أن محاكاة fcntl(2) لـ flock(3) تتطلب أن يكون FILEHANDLE مفتوحاً بنية القراءة لاستخدام LOCK_SH وتتطلب أن يكون مفتوحاً بنية الكتابة لاستخدام LOCK_EX.

لاحظ أيضاً أن بعض إصدارات "flock" لا يمكنها قفل الأشياء عبر الشبكة؛ ستحتاج لاستخدام "fcntl" الأكثر تخصيصاً للنظام للقيام بذلك. إذا أردت، يمكنك إجبار بيرل على تجاهل دالة flock(2) في نظامك، وبالتالي توفير محاكاتها الخاصة المبنية على fcntl(2)، وذلك بتمرير الخيار "-Ud_flock" إلى برنامج اضبط (Configure) عند ضبط وبناء بيرل جديد.

إليك مُلحق لعلبة البريد لأنظمة BSD.

    # استيراد ثوابت LOCK_* و SEEK_END
    use Fcntl qw(:flock SEEK_END);
    sub lock {
        my ($fh) = @_;
        flock($fh, LOCK_EX) or die "Cannot lock mailbox - $!\n";
        # وفي حال كنا نعمل على إصدارة قديمة جداً من UNIX
        # تفتقر إلى دلالات O_APPEND الحديثة...
        seek($fh, 0, SEEK_END) or die "Cannot seek - $!\n";
    }
    sub unlock {
        my ($fh) = @_;
        flock($fh, LOCK_UN) or die "Cannot unlock mailbox - $!\n";
    }
    open(my $mbox, ">>", "/usr/spool/mail/$ENV{'USER'}")
        or die "Can't open mailbox: $!";
    lock($mbox);
    print $mbox $msg,"\n\n";
    unlock($mbox);
    

في الأنظمة التي تدعم flock(2) حقيقية، تُورث الأقفال عبر استدعاءات "fork"، بينما تلك التي تضطر للجوء إلى دالة fcntl(2) الأكثر تقلباً تفقد أقفالها، مما يجعل كتابة الخوادم أمراً أصعب بكثير.

انظر أيضاً DB_File للحصول على أمثلة أخرى لـ "flock".

مسائل القابلية للنقل: "flock" في perlport.

فرع
تجري استدعاء النظام fork(2) لإنشاء عملية جديدة تشغل البرنامج نفسه عند النقطة ذاتها. تُعيد PID الابن إلى عملية الأب، و 0 إلى عملية الابن، أو "undef" إذا لم ينجح التفريع. تُشارَك واصفات الملفات (وأحياناً الأقفال على تلك الواصفات)، بينما يُنسخ كل شيء آخر. في معظم الأنظمة التي تدعم fork(2)، بُذلت عناية كبيرة لجعلها فعالة للغاية (على سبيل المثال، باستخدام تقنية النسخ عند الكتابة على صفحات البيانات)، مما يجعلها النموذج المهيمن لتعدد المهام على مدى العقود القليلة الماضية.

تحاول بيرل (Perl) إفراغ جميع الملفات المفتوحة للمخرجات قبل تفريع عملية الابن، لكن قد لا يكون هذا مدعوماً في بعض المنصات (انظر perlport). للأمان، قد تحتاج إلى ضبط $| (أو $AUTOFLUSH بالإنجليزية) أو استدعاء تابع "autoflush" الخاص بـ "IO::Handle" على أي مقابض مفتوحة لتجنب تكرار المخرجات.

إذا أجريت "fork" دون الانتظار أبداً لأبنائك، ستتراكم العمليات الزومبي (zombies). في بعض الأنظمة، يمكنك تجنب ذلك بضبط $SIG{CHLD} على "IGNORE". انظر أيضاً perlipc لمزيد من الأمثلة حول التفريع وحصد العمليات الابنة المحتضرة.

لاحظ أنه إذا ورث طفلك المتفرع (forked child) واصفات ملفات النظام مثل STDIN و STDOUT المتصلة بالفعل عبر أنبوب أو مقبس، فإنه حتى لو خرجت، فإن الخادم البعيد (مثل، لنقل، نص CGI برمج أو وظيفة في الخلفية أطلقت من صدفة بعيدة) لن يظن أنك انتهيت. يجب إعادة فتح تلك الواصفات على /dev/null إذا كان ذلك يسبب أي مشكلة.

في بعض المنصات مثل ويندوز، حيث لا يتوفر استدعاء النظام fork(2)، يمكن بناء بيرل لمحاكاة "fork" داخل مفسر بيرل. صُممت المحاكاة، على مستوى برنامج بيرل، لتكون متوافقة قدر الإمكان مع fork(2) الخاصة بـ "يونكس". ومع ذلك، فإن لها قيوداً يجب مراعاتها في الكود المقصود نقله. انظر perlfork لمزيد من التفاصيل.

مسائل القابلية للنقل: "fork" في perlport.

تنسيق
يُصرح عن تنسيق صورة لاستخدامه بواسطة دالة "write". على سبيل المثال:

    format Something =
        Test: @<<<<<<<< @||||| @>>>>>
              $str,     $%,    '$' . int($num)
    .
    $str = "widget";
    $num = $cost/$quantity;
    $~ = 'Something';
    write;
    

انظر perlform للحصول على العديد من التفاصيل والأمثلة.

هذه دالة داخلية تستخدمها "format"، على الرغم من أنه يمكنك استدعاؤها أيضاً. إنها تنسق (انظر perlform) قائمة من القيم وفقاً لمحتويات PICTURE، وتضع المخرجات في مركم مخرجات التنسيق، $^A (أو $ACCUMULATOR بالإنجليزية). في النهاية، عندما تُنفذ عملية "write"، تُكتب محتويات $^A إلى مقبض ملف ما. يمكنك أيضاً قراءة $^A ثم إعادة ضبط $^A إلى "". لاحظ أن التنسيق عادةً ما يقوم بعملية "formline" واحدة لكل سطر من النموذج، ولكن دالة "formline" نفسها لا تهتم بعدد الأسطر الجديدة المضمنة في PICTURE. هذا يعني أن وسوم "~" و "~~" تعامل PICTURE كاملة كسطر واحد. لذلك قد تحتاج لاستخدام عدة formlines لتنفيذ تنسيق سجل واحد، تماماً مثل مصرف "format".

كن حذراً إذا وضعت علامتي اقتباس مزدوجتين حول الصورة، لأن حرف "@" قد يُفهم على أنه بداية اسم مصفوفة. تعيد "formline" دائماً قيمة صحيحة. انظر perlform لمزيد من الأمثلة.

إذا كنت تحاول استخدام هذه الدالة بدلاً من "write" لالتقاط المخرجات، فقد تجد أنه من الأسهل فتح مقبض ملف إلى كمية سلمية ("open my $fh, ">", \$output") والكتابة إليها بدلاً من ذلك.

getc FILEHANDLE
تُعيد المحرف التالي من ملف الإدخال المرفق بـ FILEHANDLE، أو القيمة غير المعرفة عند نهاية الملف أو في حال حدوث خطأ (في الحالة الأخيرة تُضبط $!). إذا حُذف FILEHANDLE، تُقرأ البيانات من STDIN. هذا ليس فعالاً بشكل خاص. ومع ذلك، لا يمكن استخدامه بمفرده لجلب محارف فردية دون انتظار ضغط المستخدم على مفتاح الإدخال (Enter). لذلك، جرب شيئاً مثل:

    if ($BSD_STYLE) {
        system "stty cbreak </dev/tty >/dev/tty 2>&1";
    }
    else {
        system "stty", '-icanon', 'eol', "\001";
    }
    my $key = getc(STDIN);
    if ($BSD_STYLE) {
        system "stty -cbreak </dev/tty >/dev/tty 2>&1";
    }
    else {
        system 'stty', 'icanon', 'eol', '^@'; # ASCII NUL
    }
    print "\n";
    

تُرك تحديد ما إذا كان يجب ضبط $BSD_STYLE كتمرين للقارئ.

يمكن لدالة "POSIX::getattr" القيام بذلك بشكل أكثر قابلية للنقل على الأنظمة التي تدعي توافقها مع POSIX. انظر أيضاً وحدة "Term::ReadKey" على CPAN.

تنفذ هذه الدالة دالة مكتبة C التي تحمل الاسم نفسه، والتي تُعيد في معظم الأنظمة اسم الولوج الحالي من /etc/utmp إن وجد. إذا أعادت سلسلة فارغة، فاستخدم "getpwuid".

    my $login = getlogin || getpwuid($<) || "Kilroy";
    

لا تعتمد على "getlogin" للاستيثاق: فهي ليست آمنة مثل "getpwuid".

مسائل القابلية للنقل: "getlogin" في perlport.

تُعيد عنوان sockaddr المجمع (packed) للطرف الآخر من اتصال المقبس SOCKET.

    use Socket;
    my $hersockaddr    = getpeername($sock);
    my ($port, $iaddr) = sockaddr_in($hersockaddr);
    my $herhostname    = gethostbyaddr($iaddr, AF_INET);
    my $herstraddr     = inet_ntoa($iaddr);
    
تعيد مجموعة العمليات الحالية لـ PID المحدد. استخدم PID بقيمة 0 للحصول على مجموعة العمليات الحالية للعملية الحالية. سترفع استثناءً إذا استُخدمت على آلة لا تنفذ getpgrp(2). إذا أُغفل PID، تعيد مجموعة العمليات للعملية الحالية.

بعض الأجهزة القديمة جداً قد لا تدعم "PID != 0" وسترمي استثناءً إذا كانت "PID != 0".

مسائل القابلية للنقل: "getpgrp" في perlport.

تُعيد معرف العملية (PID) لعملية الأب.

ملاحظة لمستخدمي لينكس: بين الإصدارين v5.8.1 و v5.16.0 كانت بيرل تعالج دلالات خيوط المعالجة غير المتوافقة مع POSIX في أقلية من أنظمة لينكس (وأنظمة Debian GNU/kFreeBSD) التي استخدمت LinuxThreads، وقد أُزيلت هذه المحاكاة منذ ذلك الحين. انظر توثيق $$ للمزيد من التفاصيل.

مسائل القابلية للنقل: "getppid" في perlport.

تعيد الأولوية الحالية لعملية، أو مجموعة عمليات، أو مستخدم. (انظر getpriority(2).) سترفع استثناءً قاتلاً إذا استُخدمت على آلة لا تنفذ getpriority(2).

يمكن أن تكون "WHICH" أي واحدة من "PRIO_PROCESS"، أو "PRIO_PGRP"، أو "PRIO_USER" المستوردة من "RESOURCE CONSTANTS" في POSIX.

مسائل القابلية للنقل: "getpriority" في perlport.

هذه الروتينات هي نفسها نظيراتها في مكتبة النظام C. في سياق القائمة (list context)، تكون قيم الإرجاع من روتينات الجلب (get) المختلفة كما يلي:

 #    0        1          2           3         4
 my ( $name,   $passwd,   $gid,       $members  ) = getgr*
 my ( $name,   $aliases,  $addrtype,  $net      ) = getnet*
 my ( $name,   $aliases,  $port,      $proto    ) = getserv*
 my ( $name,   $aliases,  $proto                ) = getproto*
 my ( $name,   $aliases,  $addrtype,  $length,  @addrs ) = gethost*
 my ( $name,   $passwd,   $uid,       $gid,     $quota,
    $comment,  $gcos,     $dir,       $shell,   $expire ) = getpw*
 #    5        6          7           8         9
    

(إذا كان المدخل غير موجود، فإن القيمة المعادة هي قيمة صحيحة (true) واحدة لا معنى لها.)

يختلف المعنى الدقيق لحقل $gcos ولكنه عادةً ما يحتوي على الاسم الحقيقي للمستخدم (على عكس اسم تسجيل الدخول) ومعلومات أخرى تتعلق بالمستخدم. احذر، مع ذلك، ففي العديد من الأنظمة يتمكن المستخدمون من تغيير هذه المعلومات وبالتالي لا يمكن الوثوق بها ومن ثم يكون $gcos ملوثاً (tainted) (انظر perlsec). كما أن $passwd و $shell، كلمة مرور المستخدم المشفرة وصدفة تسجيل الدخول، ملوثان أيضاً لنفس السبب.

في السياق السلمي، تحصل على الاسم، ما لم تكن الدالة عبارة عن بحث بالاسم، وفي هذه الحالة تحصل على الشيء الآخر، أياً كان. (إذا كان المدخل غير موجود تحصل على قيمة غير معرفة.) على سبيل المثال:

    my $uid   = getpwnam($name);
    my $name  = getpwuid($num);
    my $name  = getpwent();
    my $gid   = getgrnam($name);
    my $name  = getgrgid($num);
    my $name  = getgrent();
    # الخ.
    

في روتينات getpw*() تعتبر الحقول $quota و $comment و $expire خاصة لكونها غير مدعومة في العديد من الأنظمة. إذا كان $quota غير مدعوم، فهو قيمة سلمية فارغة. إذا كان مدعوماً، فإنه عادةً ما يشفر حصة القرص (disk quota). إذا كان حقل $comment غير مدعوم، فهو قيمة سلمية فارغة. إذا كان مدعوماً فإنه عادةً ما يشفر بعض التعليقات الإدارية حول المستخدم. في بعض الأنظمة قد يكون حقل $quota هو $change أو $age، وهي حقول تتعلق بتقادم كلمة المرور. في بعض الأنظمة قد يكون حقل $comment هو $class. حقل $expire، إن وجد، يشفر فترة انتهاء صلاحية الحساب أو كلمة المرور. لمعرفة مدى التوفر والمعنى الدقيق لهذه الحقول في نظامك، يرجى مراجعة getpwnam(3) وملف pwd.h في نظامك. يمكنك أيضاً معرفة ما تعنيه حقول $quota و $comment وما إذا كان لديك حقل $expire من داخل بيرل باستخدام وحدة "Config" والقيم "d_pwquota" و "d_pwage" و "d_pwchange" و "d_pwcomment" و "d_pwexpire". ملفات كلمات المرور الخفية (Shadow) مدعومة فقط إذا كان المورد قد نفذها بالطريقة البديهية بحيث أن استدعاء روتينات مكتبة C العادية تحصل على النسخ الخفية إذا كنت تعمل بامتيازات أو إذا وجدت دوال shadow(3) كما هي موجودة في System V (وهذا يشمل سولاريس ولينكس). تلك الأنظمة التي تنفذ منشأة كلمات مرور خفية مملوكة من غير المرجح أن تُدعم.

قيمة $members التي تعيدها getgr*() هي قائمة بأسماء ولوج أعضاء المجموعة، مفصولة بمسافات.

بالنسبة لدوال gethost*()، إذا كان المتغير "h_errno" مدعوماً في C، فسيُعاد إليك عبر $? في حال فشل استدعاء الدالة. قيمة @addrs التي يعيدها الاستدعاء الناجح هي قائمة بالعناوين الخام التي يعيدها استدعاء المكتبة المقابل. في نطاق الإنترنت، يبلغ طول كل عنوان أربعة بايتات؛ يمكنك فك تجميعه بقول شيء مثل:

    my ($w,$x,$y,$z) = unpack('W4',$addr[0]);
    

تجعل مكتبة Socket هذا الأمر أسهل قليلاً:

    use Socket;
    my $iaddr = inet_aton("127.1"); # أو أي عنوان آخر
    my $name  = gethostbyaddr($iaddr, AF_INET);
    # أو بالاتجاه الآخر
    my $straddr = inet_ntoa($iaddr);
    

في الاتجاه المعاكس، لتحليل اسم مضيف إلى عنوان IP يمكنك كتابة هذا:

    use Socket;
    my $packed_ip = gethostbyname("www.perl.org");
    my $ip_address;
    if (defined $packed_ip) {
        $ip_address = inet_ntoa($packed_ip);
    }
    

تأكد من استدعاء "gethostbyname" في سياق SCALAR ومن فحص قيمة إرجاعها للتأكد من أنها معرفة.

دالة "getprotobynumber"، رغم أنها تأخذ وسيطاً واحداً فقط، إلا أن لها أسبقية معامل القائمة، لذا احذر:

    getprotobynumber $number eq 'icmp'   # خطأ
    getprotobynumber($number eq 'icmp')  # تعني هذا فعلياً
    getprotobynumber($number) eq 'icmp'  # الأفضل بهذه الطريقة
    

إذا مللت من تذكر أي عنصر في قائمة الإرجاع يحتوي على أي قيمة، فستجد واجهات بالاسم في الوحدات القياسية: "File::stat"، و "Net::hostent"، و "Net::netent"، و "Net::protoent"، و "Net::servent"، و "Time::gmtime"، و "Time::localtime"، و "User::grent". هذه الوحدات تتجاوز الأدوات المدمجة العادية، موفرةً إصدارات تعيد كائنات بأسماء مناسبة لكل حقل. على سبيل المثال:

   use File::stat;
   use User::pwent;
   my $is_theirs = (stat($filename)->uid == getpwnam($whoever)->uid);
    

على الرغم من أنها تبدو وكأنها نفس نداءات المنهج (uid)، إلا أنها ليست كذلك، لأن كائن "File::stat" مختلف عن كائن "User::pwent".

العديد من هذه الدوال ليست آمنة في بيئة متعددة الخيوط حيث يمكن لأكثر من خيط استخدامها. وبشكل خاص، دوال مثل getpwent() تكرر (iterate) لكل عملية وليس لكل خيط، لذا إذا كان خيطان يكرران في الوقت نفسه، فلن يحصل أي منهما على جميع السجلات.

تحتوي بعض الأنظمة على إصدارات آمنة للخيوط لبعض الدوال، مثل getpwnam_r() بدلاً من getpwnam(). هناك، تقوم بيرل آلياً وبشكل غير مرئي باستبدال الإصدار الآمن للخيوط، دون إشعار. وهذا يعني أن الكود الذي يعمل بأمان في بعض الأنظمة قد يفشل في أنظمة أخرى تفتقر إلى الإصدارات الآمنة للخيوط.

مسائل القابلية للنقل: من "getpwnam" في perlport إلى "endservent" في perlport.

تعيد عنوان sockaddr المحزوم لهذا الطرف من اتصال SOCKET، في حال كنت لا تعرف العنوان لأن لديك عدة عناوين IP مختلفة قد يكون الاتصال قد جاء عبرها.

    use Socket;
    my $mysockaddr = getsockname($sock);
    my ($port, $myaddr) = sockaddr_in($mysockaddr);
    printf "Connect to %s [%s]\n",
       scalar gethostbyaddr($myaddr, AF_INET),
       inet_ntoa($myaddr);
    
تستعلم عن الخيار المسمى OPTNAME المرتبط بالمقبس SOCKET عند مستوى LEVEL معين. قد توجد الخيارات عند مستويات بروتوكول متعددة اعتماداً على نوع المقبس، لكن على الأقل سيوجد أعلى مستوى للمقبس SOL_SOCKET (المُعرف في وحدة "Socket"). للاستعلام عن خيارات عند مستوى آخر، يجب توفير رقم البروتوكول للبروتوكول المناسب الذي يتحكم في الخيار. على سبيل المثال، للإشارة إلى أن خياراً ما سيُفسر بواسطة بروتوكول TCP، يجب ضبط LEVEL على رقم بروتوكول TCP، والذي يمكنك الحصول عليه باستخدام "getprotobyname".

تُعيد الدالة سلسلة مجمعة (packed string) تمثل خيار المقبس المطلوب، أو "undef" عند حدوث خطأ، مع وضع سبب الخطأ في $!. ما يوجد بالضبط في السلسلة المجمعة يعتمد على LEVEL و OPTNAME؛ ارجع إلى getsockopt(2) للتفاصيل. الحالة الشائعة هي أن يكون الخيار عدداً صحيحاً، وفي هذه الحالة تكون النتيجة عدداً صحيحاً مجمعاً، يمكنك فك ترميزه باستخدام "unpack" مع التنسيق "i" (أو "I").

إليك مثال لاختبار ما إذا كانت خوارزمية ناجل (Nagle's algorithm) مفعلة على مقبس:

    use Socket qw(:all);
    defined(my $tcp = getprotobyname("tcp"))
        or die "Could not determine the protocol number for tcp";
    # my $tcp = IPPROTO_TCP; # بديل
    my $packed = getsockopt($socket, $tcp, TCP_NODELAY)
        or die "getsockopt TCP_NODELAY: $!";
    my $nodelay = unpack("I", $packed);
    print "Nagle's algorithm is turned ",
           $nodelay ? "off\n" : "on\n";
    

مسائل القابلية للنقل: "getsockopt" في perlport.

glob EXPR
في سياق القائمة، تُعيد قائمة (قد تكون فارغة) من توسعات أسماء الملفات بناءً على قيمة EXPR كما تفعل صدفة يونكس باش (Bash). في السياق السلمي، تكرر glob عبر توسعات أسماء الملفات هذه، وتعيد "undef" عندما تنفد القائمة. إذا حُذفت EXPR، تُستخدم $_.

    # سياق القائمة
    my @txt_files  = glob("*.txt");
    my @perl_files = glob("*.pl *.pm");
    # السياق السلمي
    while (my $file = glob("*.mp3")) {
        # فعل شيء ما
    }
    

تدعم Glob أيضاً صيغة بديلة باستخدام "<" و ">" كفواصل. رغم أن هذه الصيغة مدعومة، يوصى باستخدام "glob" بدلاً منها لأنها أكثر قابلية للقراءة والبحث.

    my @txt_files  = <"*.txt">;
    

إذا كنت بحاجة إلى مطابقة ملفات غير حساسة لحالة الأحرف، فيمكن تحقيق ذلك باستخدام معامل ":nocase" في وحدة "bsd_glob".

    use File::Glob qw(:globally :nocase);
        my @txt = glob("readme*"); # README readme.txt Readme.md
    

لاحظ أن "glob" تقسم وسائطها عند المسافات البيضاء وتعامل كل جزء كنمط منفصل. على هذا النحو، فإن "glob("*.c *.h")" تطابق جميع الملفات ذات الامتداد .c أو .h. التعبير "glob(".* *")" يطابق جميع الملفات في دليل العمل الحالي. إذا أردت استخدام glob لأسماء ملفات قد تحتوي على مسافات بيضاء، فسيتعين عليك استخدام علامات اقتباس إضافية حول اسم الملف الذي يحتوي مسافات لحمايته. على سبيل المثال، لاستخدام glob لأسماء ملفات تحتوي على "e" متبوعاً بمسافة متبوعة بـ "f"، استخدم واحدة من:

    my @spacies = <"*e f*">;
    my @spacies = glob('"*e f*"');
    my @spacies = glob(q("*e f*"));
    

إذا اضطررت لتمرير متغير، يمكنك فعل ذلك:

    my @spacies = glob("'*${var}e f*'");
    my @spacies = glob(qq("*${var}e f*"));
    

إذا كانت الأقواس غير الفارغة هي حروف البدل الوحيدة المستخدمة في "glob"، فلن تُطابق أي أسماء ملفات، ولكن قد تُعاد سلاسل عديدة. على سبيل المثال، ينتج عن هذا تسع سلاسل، واحدة لكل اقتران بين الفواكه والألوان:

    my @many = glob("{apple,tomato,cherry}={green,yellow,red}");
    

هذا المعامل مُنفذ باستخدام ملحق "File::Glob" القياسي. انظر "bsd_glob" للتفاصيل، بما في ذلك "bsd_glob" التي لا تعامل المساحات البيضاء كفاصل للأنماط.

إذا استُخدم تعبير "glob" كشرط لحلقة "while" أو "for"، فسيُخصص ضمنياً لـ $_. إذا استُخدم إما تعبير "glob" أو تخصيص صريح لتعبير "glob" إلى قيمة سلمية كشرط "while"/"for"، فإن الشرط يختبر في الواقع كون قيمة التعبير معرفة، وليس قيمتها المنطقية المعتادة.

تفاصيل التنفيذ الداخلية:

هذه هي الدالة الداخلية التي تنفذ معامل "<*.c>"، ولكن يمكنك استخدامها مباشرة. نُوقش معامل "<*.c>" بمزيد من التفصيل في "معاملات الإدخال والإخراج" في perlop.

مسائل القابلية للنقل: "glob" في perlport.

gmtime EXPR
تعمل تماماً مثل "localtime"، ولكن القيم المعادة تكون محلية وفقاً لتوقيت غرينتش القياسي.

ملاحظة: عند الاستدعاء في سياق القائمة، تكون $isdst، وهي القيمة الأخيرة التي تعيدها gmtime، دائماً 0. فلا يوجد توقيت صيفي في GMT.

مسائل القابلية للنقل: "gmtime" في perlport.

تنقل "goto" التنفيذ إلى نقطة محددة في البرنامج. على عكس استدعاء الدوال، لا يعود التنفيذ إلى "goto".

يجد شكل "goto LABEL" الجملة الموسومة بـ LABEL ويستأنف التنفيذ هناك. لا يمكن استخدامها للخروج من كتلة أو روتين فرعي مُعطى لـ "sort". يمكن استخدامها للذهاب إلى أي مكان آخر تقريباً داخل النطاق الديناميكي، بما في ذلك الخروج من الروتينات الفرعية، ولكن من الأفضل عادةً استخدام بنية أخرى مثل "last" أو "die". لم يشعر مؤلف بيرل أبداً بالحاجة لاستخدام هذا الشكل من "goto" (في بيرل؛ أما في C فالأمر مختلف). (الفرق هو أن C لا تقدم حلقات موسومة مدمجة مع التحكم في الحلقات. بيرل تفعل ذلك، وهذا يحل محل معظم الاستخدامات المنظمة لـ "goto" في اللغات الأخرى.)

تتوقع الصيغة "goto EXPR" تقييم "EXPR" إلى مرجع برمجي أو اسم لصيقة. إذا قُيّم إلى مرجع برمجي، فسيُعامل مثل "goto &NAME" المذكورة أدناه. يفيد هذا خصوصًا في تنفيذ العودية الذيلية (tail recursion) عبر "goto __SUB__".

إذا تم تقييم التعبير إلى اسم لصيقة (label name)، فسيُحل نطاقه ديناميكياً. يسمح هذا بـ "goto" محسوبة كما في فورتران، ولكن لا يوصى بذلك بالضرورة إذا كنت تحسن من أجل قابلية الصيانة:

    goto ("FOO", "BAR", "GLARCH")[$i];
    

كما يظهر في هذا المثال، تُعفى "goto EXPR" من قاعدة "ما يبدو دالة". فلا يحدد زوج الأقواس الذي يليها وسيطها (بالضرورة). فالتعبير "goto("NE")."XT"" يكافئ "goto NEXT". كما أن لهذا العامل، بخلاف معظم العوامل المسماة، أسبقية الإسناد نفسها.

إن استخدام "goto LABEL" أو "goto EXPR" للقفز إلى بنية (construct) مهجور وسيُصدر تحذيراً؛ وسيصبح خطأً قاتلاً في بيرل 5.42. بينما لا يزال متاحاً، لا يجوز استخدامه للدخول في أي بنية تتطلب تهيئة، مثل روتين فرعي، أو حلقة "foreach"، أو كتلة "given". بشكل عام، لا يجوز استخدامه للقفز إلى وسيط عامل ثنائي أو قائمة، ولكن يمكن استخدامه للقفز إلى الوسيط الأول لعامل ثنائي. (المعامل "الأول" لعامل التخصيص "=" هو معامله الأيمن.) كما لا يمكن استخدامه للدخول في بنية تم تحسينها بعيداً (optimized away).

شكل "goto &NAME" مختلف تماماً عن الأشكال الأخرى لـ "goto". في الواقع، إنها ليست goto بالمعنى المعتاد على الإطلاق، وليس لها الوصمة المرتبطة بـ gotos الأخرى. بدلاً من ذلك، فإنها تخرج من الروتين الفرعي الحالي (وتفقد أي تغييرات تم تعيينها بواسطة "local") وتستدعي فوراً في مكانه الروتين الفرعي المسمى باستخدام القيمة الحالية لـ @_. يُستخدم هذا من قبل روتينات "AUTOLOAD" التي ترغب في تحميل روتين فرعي آخر ثم التظاهر بأن الروتين الفرعي الآخر قد استُدعي في المقام الأول (باستثناء أن أي تعديلات على @_ في الروتين الفرعي الحالي تُنقل إلى الروتين الفرعي الآخر). بعد "goto"، لن يتمكن حتى "caller" من معرفة أن هذا الروتين استُدعي أولاً.

لا يلزم أن يكون NAME اسم روتين فرعي؛ يمكن أن يكون متغيراً سلمياً يحتوي على مرجع كود أو كتلة يتم تقييمها إلى مرجع كود.

هذا مشابه في جوهره لبرنامج grep(1) وأقاربه، ولكنه ليس نفسه. على وجه الخصوص، هو غير مقتصر على استخدام التعبيرات النمطية.

يُقيّم BLOCK أو EXPR لكل عنصر من عناصر LIST (مع تعيين $_ محليًا لكل عنصر) ويعيد قيمة القائمة المكونة من تلك العناصر التي قُيّم التعبير لها بأنه صواب. في السياق السلمي، يعيد عدد المرات التي كان فيها التعبير صوابًا.

    my @foo = grep(!/^#/, @bar);    # استبعاد التعليقات
    

أو بشكل مكافئ،

    my @foo = grep {!/^#/} @bar;    # استبعاد التعليقات
    

لاحظ أن $_ هو اسم مستعار (alias) لقيمة القائمة، لذا يمكن استخدامه لتعديل عناصر LIST. وبينما يعد هذا مفيداً ومدعوماً، إلا أنه قد يسبب نتائج غريبة إذا لم تكن عناصر LIST متغيرات. وبالمثل، فإن grep تعيد أسماء مستعارة في القائمة الأصلية، تماماً كما يقوم متغير فهرس حلقة for بعمل اسم مستعار لعناصر القائمة. أي أن تعديل عنصر في قائمة أعادته grep (على سبيل المثال، في "foreach"، أو "map" أو "grep" أخرى) يعدل في الواقع العنصر في القائمة الأصلية. هذا عادةً شيء يجب تجنبه عند كتابة كود واضح.

انظر أيضًا "map" للحصول على قائمة مؤلفة من نتائج BLOCK أو EXPR.

hex EXPR
يفسر EXPR كسلسلة نصية سداسية عشرية ويعيد القيمة الرقمية المقابلة. إذا حُذف EXPR، يُستخدم $_.

    print hex '0xAf'; # يطبع '175'
    print hex 'aF';   # القيمة نفسها
    $valid_input =~ /\A(?:0?[xX])?(?:_?[0-9a-fA-F])*\z/
    

تتكون السلسلة السداسية عشرية من أرقام سداسية عشرية وبادئة اختيارية "0x" أو "x". يمكن أن يسبق كل رقم سداسي عشري شرطة سفلية واحدة، والتي سيتم تجاهلها. أي حرف آخر سيؤدي إلى إطلاق تحذير ويتسبب في تجاهل بقية السلسلة (حتى المسافات البيضاء البادئة، على عكس "oct"). يمكن تمثيل الأعداد الصحيحة فقط، ويؤدي طفح الأعداد الصحيحة إلى إطلاق تحذير.

لتحويل السلاسل التي قد تبدأ بأي من 0 أو "0x" أو "0b"، انظر "oct". لتمثيل شيء ما بصيغة سداسية عشرية، ابحث في "printf" و "sprintf" و "unpack".

لا توجد دالة "import" مبنية مسبقًا. إنها مجرد طريقة (دالة فرعية) عادية تُعرف (أو تُورث) بواسطة الوحدات التي ترغب في تصدير أسماء إلى وحدة أخرى. تستدعي دالة "use" طريقة "import" للحزمة المستخدمة. انظر أيضًا "use" و perlmod و Exporter.
تبحث دالة index عن سلسلة نصية داخل أخرى، ولكن بدون سلوك البطاقات العامة الموجود في مطابقة الأنماط الكاملة للتعبيرات النمطية. تعيد موضع أول ظهور لـ SUBSTR في STR عند أو بعد POSITION. إذا حُذف POSITION، يبدأ البحث من بداية السلسلة. يُعامل POSITION قبل بداية السلسلة أو بعد نهايتها كما لو كان البداية أو النهاية، على التوالي. يعتمد POSITION والقيمة المعادة على الصفر. إذا لم يُعثر على السلسلة الفرعية، تعيد "index" القيمة -1.

البحث عن أحرف أو سلاسل نصية:

    index("Perl is great", "P");     # يعيد 0
    index("Perl is great", "g");     # يعيد 8
    index("Perl is great", "great"); # يعيد أيضًا 8
    

محاولة البحث عن شيء غير موجود:

    index("Perl is great", "Z");     # يعيد -1 (لم يُعثر عليه)
    

استخدام إزاحة للعثور على الظهور الثاني:

    index("Perl is great", "e", 5);  # يعيد 10
    
int EXPR
تعيد الجزء الصحيح من EXPR. إذا أُغفل EXPR، تستخدم $_. يجب ألا تستخدم هذه الدالة للتقريب: أولاً لأنها تبتر نحو 0، وثانياً لأن تمثيلات الآلة لأرقام الفاصلة العائمة يمكن أن تنتج أحياناً نتائج غير بديهية. على سبيل المثال، int(-6.725/0.025) تنتج -268 بدلاً من -269 الصحيحة؛ وذلك لأنها في الحقيقة تشبه -268.99999999999994315658 بدلاً من ذلك. عادةً ما ستخدمك دوال "sprintf"، أو "printf"، أو "POSIX::floor" و "POSIX::ceil" بشكل أفضل من "int". علاوة على ذلك، فإن "int 'Inf'" تنتج Inf (انظر "Special floating point: infinity (Inf) and not-a-number (NaN)" في perldata للتوضيح)، وكذلك تفعل جميع الطرق البديلة المذكورة أعلاه.
تنفذ دالة ioctl(2). ستحتاج على الأرجح أولاً لقول

    require "sys/ioctl.ph";  # ربما يكون في
                             # $Config{archlib}/sys/ioctl.ph
    

للحصول على تعريفات الدوال الصحيحة. إذا لم يكن sys/ioctl.ph موجوداً أو لم يحتوي على التعريفات الصحيحة، فسيتعين عليك إنشاء تعريفاتك الخاصة، بناءً على ملفات ترويسة C مثل <sys/ioctl.h>. (هناك نص بيرل برمجي يسمى h2ph يأتي مع طقم بيرل قد يساعدك في ذلك، لكنه ليس بالأمر الهين.) ستتم قراءة و/أو كتابة SCALAR اعتماداً على FUNCTION؛ سيُمرر مؤشر C لقيمة السلسلة النصية لـ SCALAR كوسيط ثالث لنداء "ioctl" الفعلي. (إذا لم يكن لـ SCALAR قيمة نصية ولكن له قيمة عددية، فستُمرر تلك القيمة بدلاً من مؤشر للقيمة النصية. لضمان حدوث ذلك، أضف 0 إلى القيمة السلمية قبل استخدامها.) قد تكون دالتا "pack" و "unpack" مطلوبة لمعالجة قيم الهياكل المستخدمة بواسطة "ioctl".

تكون القيمة المعادة من "ioctl""fcntl") كما يلي:

    إذا أعاد نظام التشغيل:      فإن بيرل يعيد:
        -1               قيمة غير محددة (undefined value)
         0              السلسلة النصية "0 but true"
    أي شيء آخر           ذلك الرقم
    

وبذلك يعيد بيرل صوابًا (true) عند النجاح وخطأً (false) عند الفشل، ومع ذلك يمكنك بسهولة تحديد القيمة الفعلية التي أعادها نظام التشغيل:

    my $retval = ioctl(...) || -1;
    printf "System returned %d\n", $retval;
    

تُعفى السلسلة الخاصة "0 but true" من تحذيرات "Argument "..." isn't numeric" عند إجراء تحويلات رقمية غير مناسبة.

قضايا القابلية للنقل: "ioctl" في perlport.

يضم السلاسل المنفصلة في LIST في سلسلة نصية واحدة مع فصل الحقول بقيمة EXPR، ويعيد تلك السلسلة الجديدة. مثال:

   my $rec = join(':', $login,$passwd,$uid,$gid,$gcos,$home,$shell);
    

احذر من أن "join"، على عكس "split"، لا تأخذ نمطاً كوسيطها الأول. قارن "split".

عند استدعائها في سياق قائمة، تعيد قائمة تتكون من جميع مفاتيح المفروم المسمى، أو في بيرل 5.12 أو أحدث، فهارس مصفوفة. إصدارات بيرل الأقدم من 5.12 ستنتج خطأً في القواعد إذا حاولت استخدام وسيط مصفوفة. في السياق السلمي، تعيد عدد المفاتيح أو الفهار.

تُعاد مدخلات المصفوفة من أدنى فهرس أولاً.

تُعاد مدخلات المفروم بترتيب عشوائي ظاهرياً. الترتيب العشوائي الفعلي محدد لمفروم معين؛ قد تؤدي نفس السلسلة من العمليات على مفرومين إلى ترتيب مختلف لكل مفروم. أي عملية إدخال في المفروم قد تغير الترتيب، وكذلك أي حذف، باستثناء أن أحدث مفتاح أعادته "each" أو "keys" يمكن حذفه دون تغيير الترتيب. طالما أن مفروم معين غير معدل، يمكنك الاعتماد على "keys"، و "values" و "each" لإعادة نفس الترتيب لبعضها البعض بشكل متكرر. انظر "Algorithmic Complexity Attacks" في perlsec للتفاصيل حول سبب عشوائية ترتيب المفروم. وبصرف النظر عن الضمانات المقدمة هنا، فإن التفاصيل الدقيقة لخوارزمية المفروم في بيرل وترتيب التنقل في المفروم تخضع للتغيير في أي إصدار من بيرل. قد تتصرف المفرومات المقيدة (Tied hashes) بشكل مختلف عن مفرومات بيرل فيما يتعلق بالتغييرات في الترتيب عند إدخال وحذف العناصر.

كأثر جانبي، يؤدي استدعاء "keys" إلى إعادة ضبط المكرر الداخلي للـ HASH أو ARRAY (انظر "each") قبل تقديم المفاتيح. على وجه الخصوص، استدعاء "keys" في سياق فارغ (void context) يعيد ضبط المكرر دون أي عبء إضافي.

إليك طريقة أخرى لطباعة بيئتك:

    my @keys = keys %ENV;
    my @values = values %ENV;
    while (@keys) {
        print pop(@keys), '=', pop(@values), "\n";
    }
    

أو ماذا عن فرزها حسب المفتاح:

    foreach my $key (sort(keys %ENV)) {
        print $key, '=', $ENV{$key}, "\n";
    }
    

القيم المعادة هي نسخ من المفاتيح الأصلية في الهاش، لذا فإن تعديلها لن يؤثر على الهاش الأصلي. قارن مع "values".

لفرز مفروم حسب القيمة، ستحتاج لاستخدام دالة "sort". إليك فرز عددي تنازلي لمفروم حسب قيمه:

    foreach my $key (sort { $hash{$b} <=> $hash{$a} } keys %hash) {
        printf "%4d %s\n", $hash{$key}, $key;
    }
    

عند استخدامها كقيمة يسارية (lvalue) على جدول مجزأ (hash)، تتيح لك "keys" زيادة عدد سلال التجزئة المخصصة لهذا الجدول. يمكن أن يمنحك هذا قدرًا من الكفاءة إذا كنت تعلم أن الجدول سيصبح كبيرًا. (هذا يشبه تمديد المصفوفة مسبقًا عن طريق تعيين رقم أكبر لـ $#array.) إذا قلت

    keys %hash = 200;
    

عندئذ سيكون لـ %hash ما لا يقل عن 200 دلو مخصص له -- 256 منها في الواقع، لأنه يتم التقريب لأقرب قوة للرقم اثنين. سيتم الاحتفاظ بهذه الدلاء حتى لو قمت بـ "%hash = ()"، استخدم undef %hash إذا أردت تحرير مساحة التخزين بينما لا يزال %hash في النطاق. لا يمكنك تقليص عدد الدلاء المخصصة للمفروم باستخدام "keys" بهذه الطريقة (ولكن لا داعي للقلق من فعل ذلك بالصدفة، فالمحاولة ليس لها أي تأثير).

"keys @array" في سياق القيمة اليسارية (lvalue) يعد خطأً في القواعد.

بدءًا من إصدار بيرل 5.14، سمحت ميزة تجريبية لـ "keys" بأخذ تعبير سلمي. عُدّت هذه التجربة غير ناجحة، وأُزيلت اعتبارًا من بيرل 5.24.

لتجنب إرباك المستخدمين المحتملين لكودك الذين يشغلون إصدارات أقدم من Perl بأخطاء صياغة غامضة، ضع هذا النوع من الأشياء في أعلى ملفك للإشارة إلى أن كودك سيعمل فقط على إصدارات Perl الحديثة:

    use v5.12;  # لكي تعمل keys/values/each على المصفوفات
    

انظر أيضًا "each" و "values" و "sort".

يرسل إشارة إلى قائمة من العمليات. يعيد عدد الوسائط التي استُخدمت بنجاح لإرسال الإشارة (وهو ليس بالضرورة عدد العمليات التي قُتلت فعليًا، على سبيل المثال عند قتل مجموعة عمليات).

    my $cnt = kill 'HUP', $child1, $child2;
    kill 'KILL', @goners;
    

قد يكون SIGNAL إما اسم إشارة (سلسلة نصية) أو رقم إشارة. يمكن أن يبدأ اسم الإشارة ببادئة "SIG"، وبذلك يشير "FOO" و "SIGFOO" إلى الإشارة نفسها. يوصى باستخدام صيغة السلسلة النصية لـ SIGNAL من أجل القابلية للنقل لأن الإشارة نفسها قد يكون لها أرقام مختلفة في أنظمة تشغيل مختلفة.

يمكن العثور على قائمة بأسماء الإشارات التي تدعمها المنصة الحالية في $Config{sig_name}، والتي توفرها وحدة "Config". انظر Config لمزيد من التفاصيل.

اسم الإشارة السالب هو نفسه رقم الإشارة السالب، حيث يقتل مجموعات العمليات بدلاً من العمليات الفردية. على سبيل المثال، سيرسل "kill '-KILL', $pgrp" و "kill -9, $pgrp" الإشارة "SIGKILL" إلى مجموعة العمليات المحددة بالكامل. وهذا يعني أنك عادة ما ترغب في استخدام إشارات موجبة لا سالبة.

إذا كان SIGNAL إما الرقم 0 أو السلسلة النصية "ZERO" (أو "SIGZERO")، فلن يتم إرسال أي إشارة إلى العملية، ولكن تتحقق "kill" مما إذا كان من الممكن إرسال إشارة إليها (وهذا يعني باختصار أن العملية يملكها نفس المستخدم، أو أننا المستخدم الخارق (super-user)). هذا مفيد للتحقق من أن عملية الطفل لا تزال حية (حتى لو كانت مجرد عملية زومبي) ولم تغير UID الخاص بها. انظر perlport للملاحظات حول قابلية نقل هذه البنية.

يعتمد سلوك kill عندما يكون رقم العملية صفرًا أو سالبًا على نظام التشغيل. على سبيل المثال، في الأنظمة المتوافقة مع POSIX، سيرسل الصفر إشارة إلى مجموعة العمليات الحالية، وسيرسل -1 إشارة إلى جميع العمليات، وأي رقم عملية سالب آخر سيعمل كرقم إشارة سالب ويقتل مجموعة العمليات المحددة بالكامل.

إذا كان كل من SIGNAL و PROCESS سالبين، فإن النتائج غير محددة. وقد يصدر تحذير في إصدار مستقبلي.

انظر "Signals" في perlipc لمزيد من التفاصيل.

في بعض المنصات مثل ويندوز حيث لا يتوفر استدعاء النظام fork(2)، يمكن بناء بيرل لمحاكاة "fork" على مستوى المفسر. لهذه المحاكاة قيود تتعلق بـ kill يجب أخذها في الاعتبار، للكود الذي يعمل على ويندوز والكود المقصود أن يكون قابلاً للنقل.

انظر perlfork لمزيد من التفاصيل.

إذا لم تكن هناك قائمة من العمليات، فلن تُرسل أي إشارة، وتكون القيمة المعادة 0. ومع ذلك، تُستخدم هذه الصيغة أحيانًا لأنها تؤدي إلى تشغيل فحوصات التلوث (taint checks)، إذا كان إصدار بيرل لديك يدعمها. ولكن انظر "Laundering and Detecting Tainted Data" في perlsec.

قضايا القابلية للنقل: "kill" في perlport.

last LABEL
last EXPR
يشبه أمر "last" تعليمة "break" في لغة C (كما تُستخدم في الحلقات)؛ حيث يخرج فورًا من الحلقة المعنية. إذا حُذفت LABEL، يشير الأمر إلى الحلقة المغلقة الأعمق. تتيح صيغة "last EXPR"، المتوفرة بدءًا من بيرل 5.18.0، حساب اسم اللصيقة في وقت التشغيل، وهي مطابقة تمامًا لـ "last LABEL" في الجوانب الأخرى. كتلة "continue"، إن وجدت، لا تُنفذ:

    LINE: while (<STDIN>) {
        last LINE if /^$/;  # الخروج عند الانتهاء من الترويسة
        #...
    }
    

لا يمكن لـ "last" إرجاع قيمة من كتلة تعيد عادةً قيمة، مثل "eval {}" أو "sub {}" أو "do {}". فهي ستقوم بسلوك التحكم في التدفق، مما يمنع أي قيمة معادة. ولا ينبغي استخدامها للخروج من عملية "grep" أو "map".

لاحظ أن الكتلة بحد ذاتها مطابقة دلاليًا لحلقة تُنفذ مرة واحدة. لذا يمكن استخدام "last" لإحداث خروج مبكر من مثل هذه الكتلة.

انظر أيضًا "continue" لتوضيح كيفية عمل "last" و "next" و "redo".

على عكس معظم العوامل المسماة، فإن لهذا العامل أسبقية الإسناد نفسها. وهو مُعفى أيضًا من قاعدة "ما يبدو دالة"، لذا فإن "last ("foo")."bar"" سيجعل "bar" جزءًا من وسيط "last".

lc EXPR
يعيد نسخة مصغرة الأحرف (lowercased) من EXPR. إذا حُذف EXPR، يُستخدم $_.

    my $str = lc("Perl is GREAT"); # "perl is great"
    

تعتمد القيمة المعادة على عدة عوامل:

تتبع النتائج قواعد ASCII. تتغير الأحرف "A-Z" فقط إلى "a-z" على التوالي.
تحترم محلية "LC_CTYPE" الحالية لنقاط الكود < 256؛ وتستخدم قواعد يونيكود (Unicode) لنقاط الكود المتبقية (لا يمكن أن يحدث هذا الأخير إلا إذا كانت علامة UTF8 معدة أيضًا). انظر perllocale.

بدءًا من الإصدار v5.20، تستخدم Perl قواعد يونيكود كاملة إذا كانت المحلية (locale) هي UTF-8. خلاف ذلك، هناك قصور في هذا المخطط، وهو أن تغييرات حالة الأحرف التي تتجاوز الحد 255/256 ليست محددة جيدًا. على سبيل المثال، الحرف الصغير من LATIN CAPITAL LETTER SHARP S (U+1E9E) في قواعد يونيكود هو U+00DF (على منصات ASCII). ولكن تحت "use locale" (قبل v5.20 أو إذا لم تكن المحلية UTF-8)، فإن الحرف الصغير لـ U+1E9E هو نفسه، لأن 0xDF قد لا يكون LATIN SMALL LETTER SHARP S في المحلية الحالية، وليس لدى Perl طريقة لمعرفة ما إذا كان هذا المحرف موجودًا أصلاً في المحلية، فضلاً عن نقطة ترميزه. تعيد Perl نتيجة أعلى من 255 (دائمًا ما تكون محرف المدخلات دون تغيير)، لجميع الحالات (وهي ليست كثيرة) حيث سيتم تجاوز الحد 255/256؛ وبدءًا من v5.22، تطلق تحذير محلية.

وإلا، إذا كانت علامة UTF8 معدة لـ EXPR:
تُستخدم قواعد يونيكود لتغيير حالة الأحرف.
تُستخدم قواعد يونيكود لتغيير حالة الأحرف.
وإلا:
تُستخدم قواعد ASCII لتغيير حالة الأحرف. حالة الأحرف الصغيرة لأي حرف خارج نطاق ASCII هي الحرف نفسه.

ملاحظة: هذه هي الدالة الداخلية التي تنفذ هروب "\L" في السلاسل النصية المحاطة بعلامات اقتباس مزدوجة.

    my $str = "Perl is \LGREAT\E"; # "Perl is great"
lcfirst EXPR
يعيد قيمة EXPR مع تحويل الحرف الأول إلى حالة الأحرف الصغيرة. هذه هي الدالة الداخلية التي تنفذ هروب "\l" في السلاسل النصية المحاطة بعلامات اقتباس مزدوجة.

إذا حُذفت EXPR، تُستخدم $_.

تتصرف هذه الدالة بالطريقة نفسها التي تتصرف بها "lc" تحت مختلف البرغما (pragmas)، كما هو الحال في المحلية.

length EXPR
يعيد الطول بـ الأحرف لقيمة EXPR. إذا حُذف EXPR، يعيد طول $_. إذا كان EXPR غير محدد، يعيد "undef".

لا يمكن استخدام هذه الدالة على مصفوفة كاملة أو هاش لمعرفة عدد العناصر التي تحتوي عليها. لذلك، استخدم "scalar @array" و scalar keys %hash، على التوالي.

مثل جميع عمليات المحارف في Perl، تتعامل "length" عادةً مع المحارف المنطقية، وليس البايتات الفيزيائية. لمعرفة عدد البايتات التي ستشغلها سلسلة مرمزة بـ UTF-8، استخدم "length(Encode::encode('UTF-8', EXPR))" (سيتعين عليك استخدام "use Encode" أولاً). انظر Encode و perlunicode.

__LINE__
علامة (token) خاصة تترجم إلى رقم السطر الحالي. يمكن تغييرها بواسطة الآلية الموضحة في "Plain Old Comments (Not!)" في perlsyn.
ينشئ اسم ملف جديدًا مرتبطًا باسم الملف القديم. يعيد صوابًا عند النجاح، وخطأً خلاف ذلك.

قضايا القابلية للنقل: "link" في perlport.

يقوم بالشيء نفسه الذي يقوم به استدعاء النظام listen(2). يعيد صوابًا إذا نجح، وخطأً خلاف ذلك. انظر المثال في "Sockets: Client/Server Communication" في perlipc.
ربما ترغب حقًا في استخدام "my" بدلاً من ذلك، لأن "local" ليس ما يعتقده معظم الناس كـ "محلي". انظر "Private Variables via my()" في perlsub للتفاصيل.

يقوم local بتعديل المتغيرات المدرجة لتكون محلية بالنسبة للكتلة أو الملف أو eval المحيط. إذا أُدرجت أكثر من قيمة، فيجب وضع القائمة بين قوسين. انظر "Temporary Values via local()" في perlsub للحصول على التفاصيل، بما في ذلك المشكلات المتعلقة بالمصفوفات والهاشات المربوطة.

مثل "my" و "state" و "our"، يمكن لـ "local" العمل على متغير في أي مكان يظهر فيه في تعبير (باستثناء الاستيفاء في السلاسل النصية). وبخلاف الإعلانات الأخرى، يحدث تأثير "local" في وقت التشغيل، ولذلك سيطبق على الاستخدامات الإضافية للمتغير نفسه التي تُنفذ بعد الإعلان، حتى داخل الجملة نفسها. لاحظ أن هذا لا يشمل الاستخدامات داخل تعبير مُسند إلى المتغير عند جعله محليًا، لأن التعبير المُسند يُقيّم قبل جعل المتغير محليًا.

    package main;
    our $x = 2;
    {
      foo($x, local $x = $x + 1, $x); # تستلم foo() القيم (2, 3, 3)
      # $main::x هي 3 داخل استدعاء foo()
    }
    foo($x); # تستلم foo() القيمة (2) وتكون $main::x هي 2
    

يمكن أيضًا استخدام بنية "delete local EXPR" لجعل حذف عناصر المصفوفة/الهاش محليًا بالنسبة للكتلة الحالية. انظر "Localized deletion of elements of composite types" في perlsub.

localtime EXPR
تحول الوقت كما تعيده دالة time إلى قائمة مكونة من 9 عناصر مع تحليل الوقت للمنطقة الزمنية المحلية. إذا حُذف EXPR، تستخدم "localtime" الوقت الحالي (كما تعيده دالة "time").

تُستخدم عادةً على النحو التالي:

    #     0    1    2     3     4    5     6     7     8
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
                                                localtime(time);
    

جميع عناصر القائمة رقمية وتأتي مباشرة من "struct tm" في لغة C. إن $sec و $min و $hour هي الثواني والدقائق والساعات للوقت المحدد.

إن $mday هو يوم الشهر في النطاق 1..31 (أي يبدأ من 1). و $mon هو الشهر في النطاق 0..11 (أي يبدأ من 0)، حيث يشير 0 إلى يناير و 11 إلى ديسمبر. وهذا يسهل الحصول على اسم الشهر من القائمة:

    my @abbr = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
    print "$abbr[$mon] $mday";
    # $mon=9, $mday=18 gives "Oct 18"
    

يحتوي $year على عدد السنوات منذ عام 1900 (مثلاً 129 لعام 2029).

$wday هو يوم الأسبوع، حيث يشير 0 إلى الأحد و 3 إلى الأربعاء. $yday هو يوم السنة، في النطاق 0..364 (أو 0..365 في السنوات الكبيسة).

تكون $isdst صحيحة (true) إذا كان الوقت المحدد يقع ضمن وقت التوقيت الصيفي المعمول به، وخاطئة (false) خلاف ذلك.

للحصول على سلسلة تاريخ/وقت مقروءة للبشر، استخدم ""strftime"" في POSIX:

    use POSIX qw(strftime);
    my @now = localtime;
    my $now_string = strftime "%Y-%m-%d %H:%M:%S", @now;
    # e.g. "2025-11-29 15:19:02"
    

للحصول على السنة فقط، يمكنك استخدام إما ""strftime"" في POSIX:

    use POSIX qw(strftime);
    # full year:
    my $year = strftime "%Y", localtime;
    # just the last two digits of the year:
    my $ar = strftime "%y", localtime;
    

... أو الحساب اليدوي:

    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
                                                            localtime;
    # full year:
    $year += 1900;
    # just the last two digits of the year:
    my $ar = sprintf("%02d", $year % 100);
    

في سياق عددي، تُعيد "localtime" قيمة ctime(3):

    my $now_string = localtime;  # e.g., "Thu Oct 13 04:54:34 1994"
    

هذه القيمة العددية تكون دائماً بالإنجليزية، وهي ليست معتمدة على الإعدادات المحلية. للحصول على سلاسل تاريخ مماثلة ولكن معتمدة على الإعدادات المحلية، جرب على سبيل المثال:

    use POSIX qw(strftime);
    my $now_string = strftime "%a %b %e %H:%M:%S %Y", localtime;
    # or for GMT formatted appropriately for your locale:
    my $now_string = strftime "%a %b %e %H:%M:%S %Y", gmtime;
    

تُنسّق $now_string وفقاً لإعدادات LC_TIME المحلية الحالية التي يعمل البرنامج أو الخيط فيها. انظر perllocale لمعرفة كيفية إعداد وتغيير تلك الإعدادات المحلية. لاحظ أن %a و %b، وهما الصيغتان المختصرتان ليوم الأسبوع وشهر السنة، قد لا يكون طولهما بالضرورة ثلاثة أحرف.

توفر وحدتا Time::gmtime و Time::localtime آلية وصول مريحة بالاسم لدالتي "gmtime" و "localtime" على التوالي.

لتمثيل شامل للتاريخ والوقت، انظر إلى وحدة DateTime على CPAN.

استخدم دالة "gmtime" المدمجة للحصول على توقيت جرينتش بدلاً من الوقت المحلي.

انظر أيضًا وحدة "Time::Local" (لتحويل الثواني والدقائق والساعات وما شابه ذلك مرة أخرى إلى القيمة الصحيحة التي تعيدها دالة "time")، ودالة "mktime" في وحدة POSIX.

قضايا قابلية النقل: "localtime" في perlport.

تضع هذه الدالة قفلاً استشارياً على متغير مشترك أو كائن مُشار إليه موجود في THING حتى يخرج القفل عن النطاق.

القيمة المُعادة هي المتغير العددي نفسه إذا كان المعامل عددي، أو مرجع (reference) إذا كان المعامل جدول تجزئة أو مصفوفة أو روتين فرعي.

تعتبر "lock" "كلمة مفتاحية ضعيفة"؛ وهذا يعني أنه إذا عَرّفت دالة بهذا الاسم (قبل أي استدعاءات لها)، فستُستدعى تلك الدالة بدلاً منها. إذا لم تكن تحت "use threads::shared" فلن تفعل شيئًا. انظر threads::shared.

log EXPR
تُعيد اللوغاريتم الطبيعي (الأساس e) لـ EXPR. إذا حُذف EXPR، تُعيد لوغاريتم $_. للحصول على لوغاريتم لأساس آخر، استخدم الجبر الأساسي: لوغاريتم عدد للأساس N يساوي اللوغاريتم الطبيعي لذلك العدد مقسوماً على اللوغاريتم الطبيعي لـ N. على سبيل المثال:

    sub log10 {
        my $n = shift;
        return log($n)/log(10);
    }
    

انظر أيضاً "exp" للعملية العكسية.

lstat FILEHANDLE
lstat EXPR
lstat DIRHANDLE
تفعل نفس ما تفعله دالة "stat" (بما في ذلك ضبط واصف الملف الخاص "_") لكنها تجلب معلومات الرابط الرمزي بدلاً من الملف الذي يشير إليه الرابط الرمزي. إذا كانت الروابط الرمزية غير مفعلة في نظامك، فسيتم إجراء "stat" عادي. لمعلومات أكثر تفصيلاً، يرجى مراجعة توثيق "stat".

إذا حُذف EXPR، يتم جلب معلومات $_.

قضايا قابلية النقل: "lstat" في perlport.

عامل المطابقة. انظر "Regexp Quote-Like Operators" في perlop.
تُقيم الكتلة (BLOCK) أو التعبير (EXPR) لكل عنصر في القائمة LIST (مع تعيين $_ محلياً لكل عنصر) وتُكوّن قائمة من نتائج كل تقييم. قد ينتج عن كل عنصر من LIST صفر أو واحد أو أكثر من العناصر في القائمة المولدة، لذا قد يختلف عدد العناصر في القائمة المولدة عن عددها في LIST. في السياق العددي، تُعيد إجمالي عدد العناصر المولدة. في سياق القائمة، تُعيد القائمة المولدة.

    my @chars = map(chr, @numbers);
    

تُترجم قائمة من الأرقام إلى المحارف المقابلة لها.

    my @squares = map { $_ * $_ } @numbers;
    

تُترجم قائمة من الأرقام إلى قيمها المربعة.

    my @squares = map { $_ > 5 ? ($_ * $_) : () } @numbers;
    

توضح أن عدد العناصر المعادة يمكن أن يختلف عن عدد عناصر المدخلات. لإسقاط عنصر، أعد قائمة فارغة (). يمكن تحقيق ذلك أيضاً بكتابة

    my @squares = map { $_ * $_ } grep { $_ > 5 } @numbers;
    

مما يجعل القصد أكثر وضوحاً.

تُعيد دالة Map دائماً قائمة، يمكن إسنادها إلى جدول تجزئة (hash) بحيث تصبح العناصر أزواج مفتاح/قيمة. انظر perldata لمزيد من التفاصيل.

    my %hash = map { get_a_key_for($_) => $_ } @array;
    

هي مجرد طريقة طريفة لكتابة

    my %hash;
    foreach (@array) {
        $hash{get_a_key_for($_)} = $_;
    }
    

لاحظ أن $_ هو اسم مستعار لقيمة القائمة، لذا يمكن استخدامه لتعديل عناصر LIST. ورغم أن هذا مفيد ومدعوم، إلا أنه قد يسبب نتائج غريبة إذا لم تكن عناصر LIST متغيرات. استخدام حلقة "foreach" عادية لهذا الغرض سيكون أوضح في معظم الحالات. انظر أيضاً "grep" للحصول على قائمة مكونة من العناصر التي يكون تقييم الكتلة أو التعبير لها صحيحاً.

تبدأ "{" كلاً من مراجع جداول التجزئة والكتل البرمجية، لذا قد تكون "map { ..." إما بداية map BLOCK LIST أو map EXPR, LIST. لأن Perl لا تنظر للأمام بحثًا عن "}" المغلقة، يتعين عليها التخمين بناءً على ما تجده مباشرة بعد "{". عادةً ما تصيب في تخمينها، ولكن إذا أخطأت فلن تدرك أن هناك خطأ ما حتى تصل إلى "}" وتواجه الفاصلة المفقودة (أو غير المتوقعة). سيُبلغ عن خطأ الصيغة بالقرب من "}"، ولكن ستحتاج إلى تغيير شيء ما بالقرب من "{" مثل استخدام عامل أحادي "+" أو فاصلة منقوطة لمساعدة Perl:

 my %hash = map {  "\L$_" => 1  } @array # perl guesses EXPR. wrong
 my %hash = map { +"\L$_" => 1  } @array # perl guesses BLOCK. right
 my %hash = map {; "\L$_" => 1  } @array # this also works
 my %hash = map { ("\L$_" => 1) } @array # as does this
 my %hash = map {  lc($_) => 1  } @array # and this.
 my %hash = map +( lc($_) => 1 ), @array # this is EXPR and works!
 my %hash = map  ( lc($_), 1 ),   @array # evaluates to (1, @array)
    

أو لإجبار استخدام منشئ جدول تجزئة مجهول، استخدم "+{":

    my @hashes = map +{ lc($_) => 1 }, @array # EXPR, so needs
                                              # comma at end
    

للحصول على قائمة من جداول التجزئة المجهولة، لكل منها مدخل واحد فقط.

تنشئ دالة جديدة مسماة في نطاق الفئة (class) التي تظهر فيها. هذا صالح فقط داخل تصريح "class".
mkdir FILENAME,MODE
mkdir FILENAME
تنشئ المجلد المحدد بواسطة FILENAME، مع الصلاحيات المحددة بواسطة MODE (كما تُعدلها دالة "umask"). إذا نجحت تُعيد قيمة صحيحة؛ وإلا فإنها تُعيد قيمة خاطئة وتضبط $! (الخطأ). MODE يكون مبدئياً 0777 إذا حُذف، و FILENAME يكون مبدئياً $_ إذا حُذف.

بشكل عام، من الأفضل إنشاء المجلدات مع MODE متساهل وترك المستخدم يعدل ذلك باستخدام "umask" الخاص به بدلاً من توفير MODE تقييدي وعدم منح المستخدم أي وسيلة ليكون أكثر تساهلاً. الاستثناءات لهذه القاعدة هي عندما يجب الحفاظ على خصوصية الملف أو المجلد (ملفات البريد، على سبيل المثال). يناقش توثيق "umask" اختيار MODE بمزيد من التفصيل. إذا ضُبطت بتات في MODE غير بتات الصلاحيات، فقد تكون النتيجة معتمدة على التنفيذ، وفقاً لمعيار POSIX 1003.1-2008.

لاحظ أنه وفقاً لمعيار POSIX 1003.1-1996، قد يحتوي FILENAME على أي عدد من الشرطات المائلة اللاحقة. بعض أنظمة التشغيل ونظم الملفات لا تتعامل مع هذا بشكل صحيح، لذا تقوم Perl آلياً بإزالة كل الشرطات المائلة اللاحقة.

لإنشاء هيكل مجلدات بشكل متكرر (recursively)، انظر إلى دالة "make_path" في وحدة File::Path.

تستدعي دالة System V IPC المسماة msgctl(2). سيتعين عليك على الأرجح قول

    use IPC::SysV;
    

أولاً للحصول على تعريفات الثوابت الصحيحة. إذا كان CMD هو "IPC_STAT"، فيجب أن يكون ARG متغيراً يحمل هيكل "msqid_ds" المُعاد. تُعيد نتائج مثل "ioctl": القيمة غير المعرفة للخطأ، أو "0 but true" للصفر، أو قيمة الإعادة الفعلية خلاف ذلك. انظر أيضاً "SysV IPC" في perlipc وتوثيق "IPC::SysV" و "IPC::Semaphore".

قضايا قابلية النقل: "msgctl" في perlport.

تستدعي دالة System V IPC المسماة msgget(2). تُعيد معرف طابور الرسائل، أو "undef" عند حدوث خطأ. انظر أيضاً "SysV IPC" في perlipc وتوثيق "IPC::SysV" و "IPC::Msg".

قضايا قابلية النقل: "msgget" في perlport.

تستدعي دالة System V IPC المسماة msgrcv لاستلام رسالة من معرف طابور الرسائل ID إلى المتغير VAR بحد أقصى لحجم الرسالة هو SIZE. لاحظ أنه عند استلام رسالة، سيكون نوع الرسالة كعدد صحيح طويل أصلي هو أول شيء في VAR، يتبعه الرسالة الفعلية. يمكن فتح هذا الحزم باستخدام "unpack("l! a*")". تلوث المتغير. تُعيد قيمة صحيحة إذا نجحت، وخاطئة عند حدوث خطأ. انظر أيضاً "SysV IPC" في perlipc وتوثيق "IPC::SysV" و "IPC::Msg".

قضايا قابلية النقل: "msgrcv" في perlport.

تستدعي دالة System V IPC المسماة msgsnd لإرسال الرسالة MSG إلى طابور الرسائل ذي المعرف ID. يجب أن تبدأ MSG بنوع الرسالة كعدد صحيح طويل أصلي، يتبعه الرسالة نفسها. يمكن تحقيق هذا النوع من الحزم باستخدام "pack("l! a*", $type, $message)". تُعيد قيمة صحيحة إذا نجحت، وخاطئة عند حدوث خطأ. انظر أيضاً "SysV IPC" في perlipc وتوثيق "IPC::SysV" و "IPC::Msg".

قضايا قابلية النقل: "msgsnd" في perlport.

تُصرح "my" بأن المتغيرات المدرجة محلية (معجمياً) للكتلة المحيطة، أو الملف، أو "eval". إذا أُدرج أكثر من متغير واحد، يجب وضع القائمة بين قوسين.

لاحظ أنه مع القائمة الموضوعة بين قوسين، يمكن استخدام "undef" كعنصر نائب وهمي، على سبيل المثال لتخطي إسناد القيم الأولية:

    my ( undef, $min, $hour ) = localtime;
    

مثل "state" و "local" و "our"، يمكن لـ "my" أن تعمل على متغير أينما ظهر في تعبير (باستثناء الاستيفاء داخل السلاسل النصية). لن ينطبق التصريح على الاستخدامات الإضافية لنفس المتغير حتى العبارة التالية. وهذا يعني أن الاستخدامات الإضافية لهذا المتغير ضمن نفس العبارة ستتصرف كما كانت قبل حدوث ذلك التصريح، أو تؤدي إلى خطأ strict 'vars'، حسب الاقتضاء.

    package main;
    our $x = 2;
    foo($x, my $x = $x + 1, $x); # foo() receives (2, 3, 2)
    foo($x, $main::x);           # foo() receives (3, 2)
    

إعادة التصريح عن متغير في نفس النطاق أو البيان سيؤدي إلى "حجب" (shadow) التصريح السابق، مما ينشئ نسخة جديدة ويمنع الوصول إلى النسخة السابقة. هذا عادة ما يكون غير مرغوب فيه، وإذا كانت التحذيرات مفعلة، فسيؤدي ذلك إلى تحذير في فئة "shadow".

لا تزال الدلالات الدقيقة وواجهة TYPE و ATTRS قيد التطوير. قد يكون TYPE كلمة مجردة، أو ثابتاً مصرحاً به باستخدام "use constant"، أو "__PACKAGE__". وهو مرتبط حالياً باستخدام برغما fields، وتتم معالجة السمات (attributes) باستخدام برغما attributes، أو بدءاً من Perl 5.8.0 أيضاً عبر وحدة Attribute::Handlers. انظر "Private Variables via my()" في perlsub للتفاصيل.

next LABEL
next EXPR
أمر "next" يشبه بيان "continue" في لغة C؛ فهو يبدأ التكرار التالي للحلقة:

    LINE: while (<STDIN>) {
        next LINE if /^#/;  # تجاهل التعليقات
        #...
    }
    

لاحظ أنه إذا كانت هناك كتلة "continue" فيما سبق، فإنها ستنفذ حتى في السطور التي تم تجاهلها. إذا حُذفت LABEL، فإن الأمر يشير إلى الحلقة المحيطة الأعمق. صيغة "next EXPR"، المتوفرة منذ Perl 5.18.0، تسمح بحساب اسم اللاصقة في وقت التشغيل، وتكون مطابقة تماماً لـ "next LABEL".

لا يمكن لـ "next" إرجاع قيمة من كتلة تُرجع عادةً قيمة، مثل "eval {}" أو "sub {}" أو "do {}". ستقوم بسلوك التحكم في التدفق الخاص بها، والذي يمنع أي قيمة إرجاع. لا ينبغي استخدامها للخروج من عملية "grep" أو "map".

لاحظ أن الكتلة بمفردها مطابقة دلالياً لحلقة تُنفذ مرة واحدة. بالتالي فإن "next" ستخرج من مثل هذه الكتلة مبكراً.

انظر أيضًا "continue" لتوضيح كيفية عمل "last" و "next" و "redo".

على عكس معظم العوامل المسماة، فإن لهذا العامل نفس أسبقية الإسناد. وهو مستثنى أيضاً من قاعدة "يبدو كدالة"، لذا فإن "next ("foo")."bar"" ستجعل "bar" جزءاً من المعامل لـ "next".

انظر دالة "use"، والتي تُعد "no" عكسها.
oct EXPR
تفسر EXPR كسلسلة نصية ثمانية (octal) وتُعيد القيمة المقابلة لها. تتكون السلسلة الثمانية من أرقام ثمانية، وبدءاً من Perl 5.33.5، بادئة اختيارية "0o" أو "o". قد يسبق كل رقم ثماني شرطة سفلية واحدة، سيتم تجاهلها. (إذا صادف أن بدأت EXPR بـ "0x" أو "x"، فسيتم تفسيرها كسلسلة ست عشرية. إذا بدأت EXPR بـ "0b" أو "b"، فسيتم تفسيرها كسلسلة ثنائية. يتم تجاهل المسافات البيضاء البادئة في الحالات الثلاث جميعاً.) الكود التالي سيتعامل مع العشري والثنائي والثماني والست عشري في تدوين Perl القياسي:

    $val = oct($val) if $val =~ /^0/;
    

إذا حُذف EXPR، يتم استخدام $_. للقيام بالعكس (إنتاج رقم بالصيغة الثمانية)، استخدم "sprintf" أو "printf":

    my $dec_perms = (stat("filename"))[2] & 07777;
    my $oct_perm_str = sprintf "%o", $perms;
    

تُستخدم دالة "oct" عادةً عندما نحتاج لتحويل سلسلة نصية مثل 644 إلى نمط ملف، على سبيل المثال. ورغم أن Perl تُحول السلاسل النصية آلياً إلى أرقام حسب الحاجة، إلا أن هذا التحويل الآلي يفترض أن الأساس هو 10.

يتم تجاهل المسافات البيضاء البادئة بدون تحذير، وكذلك أي أرقام غير لاحقة، مثل العلامة العشرية (تتعامل "oct" فقط مع الأعداد الصحيحة غير السالبة، وليس الأعداد الصحيحة السالبة أو الأعداد العشرية).

تربط واصف ملف (FILEHANDLE) داخلي بالملف الخارجي المحدد بواسطة EXPR. سيسمح لك واصف الملف هذا لاحقاً بإجراء عمليات الإدخال/الإخراج على ذلك الملف، مثل القراءة منه أو الكتابة فيه.

بدلاً من اسم الملف، يمكنك تحديد أمر خارجي (بالإضافة إلى قائمة معاملات اختيارية) أو مرجع عددي، من أجل فتح واصفات ملفات على الأوامر أو المتغيرات العددية في الذاكرة، على التوالي.

يتبع ذلك مرجع شامل لـ "open". للحصول على مقدمة أسهل لأساسيات "open"، انظر أيضاً صفحة الدليل perlopentut.

العمل مع الملفات
في أغلب الأحيان، يتم استدعاء "open" بثلاثة معاملات: واصف الملف المطلوب (عادة متغير عددي فارغ)، يليه MODE (عادة وصف نصي يصف نمط الإدخال/الإخراج الذي سيستخدمه واصف الملف)، ثم اسم الملف الذي سيشير إليه واصف الملف الجديد.
أمثلة بسيطة
القراءة من ملف:

    open(my $fh, "<", "input.txt")
        or die "Can't open < input.txt: $!";
    # معالجة كل سطر في input.txt
    while (my $line = readline($fh)) {
        #
        # ... افعل شيئاً مثيراً للاهتمام مع $line هنا ...
        #
    }
    

أو الكتابة في ملف:

    open(my $fh, ">", "output.txt")
        or die "Can't open > output.txt: $!";
    print $fh "This line gets printed into output.txt.\n";
    

للحصول على ملخص لعمليات واصفات الملفات الشائعة مثل هذه، راجع "Files and I/O" في perlintro.

حول مقابض الملفات
المعامل الأول لـ "open"، والمسمى FILEHANDLE في هذا المرجع، عادةً ما يكون متغيرًا سلميًا (scalar). (توجد استثناءات موصوفة في "اعتبارات أخرى" أدناه.) إذا نجح استدعاء "open"، فسيُسند إلى التعبير المقدم كـ FILEHANDLE مقبض ملف مفتوح. يوفر مقبض الملف هذا مرجعًا داخليًا لملف خارجي محدد، يُخزن بشكل ملائم في متغير Perl، ويكون جاهزًا لعمليات الإدخال والإخراج مثل القراءة والكتابة.
حول الأنماط
عند استدعاء "open" بثلاثة وسائط أو أكثر، فإن الوسيط الثاني -- المسمى MODE هنا -- يحدد وضع الفتح. عادةً ما يكون MODE عبارة عن سلسلة نصية حرفية تتكون من محارف خاصة تحدد دور الإدخال/الإخراج المقصود لمقبض الملف الجاري إنشاؤه: ما إذا كان للقراءة فقط، أو للقراءة والكتابة، وهكذا.

إذا كان MODE هو "<"، فسيُفتح الملف للإدخال (للقراءة فقط). وإذا كان MODE هو ">"، فسيُفتح الملف للإخراج، مع اقتطاع الملفات الموجودة مسبقًا ("clobbered") وإنشاء الملفات غير الموجودة من جديد. أما إذا كان MODE هو ">>"، فسيُفتح الملف للإلحاق، مع إنشائه أيضًا إذا لزم الأمر.

يمكنك وضع "+" أمام ">" أو "<" للإشارة إلى أنك تريد وصولاً للقراءة والكتابة معًا إلى الملف؛ وبالتالي يُفضل دائمًا وضع "+<" لتحديثات القراءة/الكتابة -- لأن وضع "+>" سيسحق الملف أولاً. لا يمكنك عادةً استخدام أي من وضعي القراءة والكتابة لتحديث ملفات النصوص، لأنها تحتوي على سجلات متغيرة الطول. انظر مفتاح -i في perlrun لنهج أفضل. يُنشأ الملف بصلاحيات 0666 معدلة بواسطة قيمة "umask" الخاصة بالعملية.

تتوافق هذه البادئات المتنوعة مع أنماط fopen(3) وهي "r"، و "r+"، و "w"، و "w+"، و "a"، و "a+".

مزيد من الأمثلة على الأنماط المختلفة قيد العمل:

 # فتح ملف للدمج
 open(my $log, ">>", "/usr/spool/news/twitlog")
     or warn "Couldn't open log file; discarding input";
 # فتح ملف للقراءة والكتابة
 open(my $dbase, "+<", "dbase.mine")
     or die "Can't open 'dbase.mine' for update: $!";
    
التحقق من القيمة المعادة
تعيد Open قيمة غير صفرية عند النجاح، والقيمة غير المعرفة خلاف ذلك. إذا كان "open" يتضمن أنبوبًا (pipe)، فإن القيمة المعادة تكون معرف العملية (pid) للعملية الفرعية.

عند فتح ملف، نادراً ما يكون من الجيد الاستمرار إذا فشل الطلب، لذا تُستخدم "open" بشكل متكرر مع "die". حتى لو كنت تريد أن يفعل الكود الخاص بك شيئًا آخر غير "die" عند فشل الفتح، يجب عليك دائمًا التحقق من القيمة المعادة من فتح الملف.

تحديد طبقات الإدخال/الإخراج في MODE
يمكنك استخدام صيغة المعاملات الثلاثة لـ open لتحديد طبقات الإدخال/الإخراج (يُشار إليها أحيانًا باسم "الضوابط") لتطبيقها على مقبض الملف الجديد. تؤثر هذه على كيفية معالجة المدخلات والمخرجات (راجع open و PerlIO لمزيد من التفاصيل). على سبيل المثال:

    # يحمل PerlIO::encoding آليًا
    open(my $fh, "<:encoding(UTF-8)", $filename)
        || die "Can't open UTF-8 encoded $filename: $!";
    

يفتح هذا الملف المرمز بـ UTF8 والذي يحتوي على محارف يونيكود؛ راجع perluniintro. لاحظ أنه إذا حُددت الطبقات في صيغة المعاملات الثلاثة، فإن الطبقات المبدئية المخزنة في "${^OPEN}" (تُضبط عادةً بواسطة برجمة open أو المفتاح "-CioD") تُتجاهل. كما ستُتجاهل تلك الطبقات أيضًا إذا حددت نقطتين رأسيتين دون اسم يتبعهما. في هذه الحالة، تُستخدم الطبقة المبدئية لنظام التشغيل (:raw على Unix، و :crlf على Windows).

في بعض الأنظمة (بشكل عام، الأنظمة القائمة على DOS و Windows) تكون "binmode" ضرورية عندما لا تعمل مع ملف نصي. من أجل قابلية النقل، من الجيد دائماً استخدامها عندما يكون ذلك مناسباً، وعدم استخدامها مطلقاً عندما لا تكون مناسبة. أيضاً، يمكن للأشخاص ضبط الإدخال والإخراج الخاص بهم ليكون مبدئياً بترميز UTF8 Unicode، وليس بايتات.

كحالة خاصة، صيغة المعاملات الثلاثة مع نمط قراءة/كتابة ويكون المعامل الثالث هو "undef":

    open(my $tmp, "+>", undef) or die ...
    

يفتح مقبض ملف لملف مؤقت مجهول فارغ أُنشئ حديثًا. (يحدث هذا تحت أي نمط، مما يجعل "+>" النمط الوحيد المفيد والمنطقي للاستخدام.) ستحتاج إلى "seek" للقيام بالقراءة.

فتح مقبض ملف إلى متغير سلمي في الذاكرة
يمكنك فتح مقابض ملفات مباشرةً إلى متغيرات Perl السلمية بدلاً من ملف أو مورد آخر خارجي عن البرنامج. للقيام بذلك، قدم مرجعًا (reference) لذلك المتغير السلمي كمعامل ثالث لـ "open"، هكذا:

 open(my $memory, ">", \$var)
     or die "Can't open memory file: $!";
 print $memory "foo!\n";    # سيظهر المخرج في $var
    

لـ (إعادة) فتح "STDOUT" أو "STDERR" كملف في الذاكرة، أغلقه أولاً:

    close STDOUT;
    open(STDOUT, ">", \$variable)
        or die "Can't open STDOUT: $!";
    

تُعامل المتغيرات السلمية لملفات الذاكرة كسلاسل ثمانية (octet strings): ما لم يُفتح الملف مع الاقتطاع، لا يجوز أن يحتوي المتغير السلمي على أي نقاط ترميز تزيد عن 0xFF.

يمكن أن يفشل فتح ملفات الذاكرة لأسباب متنوعة. وكما هو الحال مع أي "open" آخر، تحقق من القيمة المعادة للنجاح.

ملاحظة تقنية: تعمل هذه الميزة فقط عندما تُبنى Perl مع PerlIO -- وهو الوضع المبدئي، باستثناء تثبيتات Perl القديمة (ما قبل 5.16) التي ضُبطت لعدم تضمينه (مثلاً عبر "Configure -Uuseperlio"). يمكنك معرفة ما إذا كانت نسخة Perl الخاصة بك قد بُنيت مع PerlIO عن طريق تشغيل "perl -V:useperlio". إذا كانت النتيجة 'define'، فلديك PerlIO؛ وخلاف ذلك ليس لديك.

راجع perliol للحصول على معلومات مفصلة حول PerlIO.

فتح مقبض ملف إلى أمر
إذا كان MODE هو "|-"، فسيُفسر اسم الملف كأمر يُوجه المخرج إليه عبر أنبوب، وإذا كان MODE هو "-|"، فسيُفسر اسم الملف كأمر يوجه المخرج إلينا عبر أنبوب. في صيغة المعاملين (أو المعامل الواحد)، يجب استبدال الشرطة ("-") بالأمر. راجع "استخدام open() للتواصل بين العمليات (IPC)" في perlipc لمزيد من الأمثلة على ذلك. (لا يُسمح لك بـ "open" لأمر يوجه الأنابيب للداخل و الخارج معًا، ولكن راجع IPC::Open2 و IPC::Open3 و "الاتصال ثنائي الاتجاه مع عملية أخرى" في perlipc للبدائل.)

 open(my $article_fh, "-|", "caesar <$article")  # فك تعمية
                                                 # المقال
     or die "Can't start caesar: $!";
 open(my $article_fh, "caesar <$article |")      # بالمثل
     or die "Can't start caesar: $!";
 open(my $out_fh, "|-", "sort >Tmp$$")    # $$ هو معرف عمليتنا
     or die "Can't start sort: $!";
    

في صيغة فتح الأنابيب التي تأخذ ثلاثة معاملات أو أكثر، إذا حُددت LIST (معاملات إضافية بعد اسم الأمر)، فستصبح LIST معاملات للأمر المستدعى إذا كانت المنصة تدعم ذلك. إن معنى "open" بأكثر من ثلاثة معاملات للأنماط غير الأنبوبية لم يُحدد بعد، ولكن "الطبقات" التجريبية قد تعطي معاملات LIST الإضافية معنى.

إذا فتحت أنبوبًا على الأمر "-" (أي، حددت إما "|-" أو "-|" مع صيغ المعامل الواحد أو المعاملين لـ "open")، فسيُجرى "fork" ضمني، وبالتالي تعيد "open" قيمتين: في العملية الأب تعيد pid للعملية الابن، وفي العملية الابن تعيد 0 (مُعرفة). استخدم defined($pid) أو "//" لتحديد ما إذا كان الفتح ناجحًا.

على سبيل المثال، استخدم إما

   my $child_pid = open(my $from_kid, "-|")
        // die "Can't fork: $!";
    

أو

   my $child_pid = open(my $to_kid,   "|-")
        // die "Can't fork: $!";
    

متبوعًا بـ

    if ($child_pid) {
        # أنا الأب:
        # إما الكتابة إلى $to_kid أو القراءة من $from_kid
        ...
       waitpid $child_pid, 0;
    } else {
        # أنا الابن؛ استخدم STDIN/STDOUT بشكل طبيعي
        ...
        exit;
    }
    

يتصرف مقبض الملف بشكل طبيعي بالنسبة للأب، ولكن عمليات الإدخال/الإخراج إلى مقبض الملف هذا تُنقل عبر أنبوب من/إلى STDOUT/STDIN الخاص بالعملية الابنة. في العملية الابنة، لا يُفتح مقبض الملف -- يحدث الإدخال/الإخراج من/إلى STDOUT/STDIN الجديد. عادةً ما يُستخدم هذا مثل الفتح عبر الأنابيب العادي عندما تريد ممارسة مزيد من التحكم في كيفية تنفيذ أمر الأنبوب، مثل عند التشغيل بـ setuid ولا تريد مسح أوامر الصدفة بحثًا عن محارف التحويل.

الكتل التالية متكافئة تقريبًا:

    open(my $fh, "|tr '[a-z]' '[A-Z]'");
    open(my $fh, "|-", "tr '[a-z]' '[A-Z]'");
    open(my $fh, "|-") || exec 'tr', '[a-z]', '[A-Z]';
    open(my $fh, "|-", "tr", '[a-z]', '[A-Z]');
    open(my $fh, "cat -n '$file'|");
    open(my $fh, "-|", "cat -n '$file'");
    open(my $fh, "-|") || exec "cat", "-n", $file;
    open(my $fh, "-|", "cat", "-n", $file);
    

يوضح المثالان الأخيران في كل كتلة الأنبوب في "صيغة القائمة"، وهي ليست مدعومة بعد على جميع المنصات. (إذا كانت منصتك تحتوي على "fork" حقيقي، مثل Linux و macOS، يمكنك استخدام صيغة القائمة؛ كما أنها تعمل على Windows مع Perl 5.22 أو أحدث.) قد ترغب في استخدام صيغة القائمة للأنبوب حتى تتمكن من تمرير معاملات حرفية إلى الأمر دون خطر قيام الصدفة بتفسير أي محارف صدفة فوقية فيها. ومع ذلك، فإن هذا يمنعك أيضًا من فتح الأنابيب للأوامر التي تحتوي عمدًا على محارف صدفة فوقية، مثل:

    open(my $fh, "|cat -n | expand -4 | lpr")
        || die "Can't open pipeline to lpr: $!";
    

راجع "فتح الأنابيب الآمن" في perlipc لمزيد من الأمثلة على ذلك.

نسخ مقابض الملفات (Duping)
يمكنك أيضًا، على غرار صدفة Bourne، تحديد EXPR يبدأ بـ ">&"، وفي هذه الحالة يُفسر باقي السلسلة النصية كاسم لمقبض ملف (أو واصف ملف، إذا كان رقميًا) لنسخه (كما في dup(2)) وفتحه. يمكنك استخدام "&" بعد ">"، و ">>"، و "<"، و "+>"، و "+>>"، و "+<". يجب أن يطابق النمط الذي تحدده نمط مقبض الملف الأصلي. (نسخ مقبض الملف لا يأخذ في الاعتبار أي محتويات موجودة في مخازن الإدخال/الإخراج المؤقتة.) إذا استخدمت صيغة المعاملات الثلاثة، فيمكنك تمرير إما رقم، أو اسم مقبض ملف، أو "مرجع إلى glob" عادي.

إليك نص برمجي يحفظ، ويعيد توجيه، ويستعيد "STDOUT" و "STDERR" باستخدام طرق متنوعة:

    #!/usr/bin/perl
    open(my $oldout, ">&STDOUT")
        or die "Can't dup STDOUT: $!";
    open(OLDERR,     ">&", \*STDERR)
        or die "Can't dup STDERR: $!";
    open(STDOUT, '>', "foo.out")
        or die "Can't redirect STDOUT: $!";
    open(STDERR, ">&STDOUT")
        or die "Can't dup STDOUT: $!";
    select STDERR; $| = 1;  # جعلها غير مخزنة مؤقتًا
    select STDOUT; $| = 1;  # جعلها غير مخزنة مؤقتًا
    print STDOUT "stdout 1\n";  # هذا يعمل من أجل
    print STDERR "stderr 1\n";  # العمليات الفرعية أيضًا
    open(STDOUT, ">&", $oldout)
        or die "Can't dup \$oldout: $!";
    open(STDERR, ">&OLDERR")
        or die "Can't dup OLDERR: $!";
    print STDOUT "stdout 2\n";
    print STDERR "stderr 2\n";
    

إذا حددت '<&=X'، حيث يكون "X" رقم واصف ملف أو مقبض ملف، فإن Perl ستفعل ما يعادل دالة fdopen(3) في لغة C لواصف الملف هذا (ولن تستدعي dup(2))؛ وهذا أكثر توفيرًا لواصفات الملفات. على سبيل المثال:

    # فتح للإدخال، مع إعادة استخدام fileno لـ $fd
    open(my $fh, "<&=", $fd)
    

أو

    open(my $fh, "<&=$fd")
    

أو

    # فتح للإلحاق، باستخدام fileno لـ $oldfh
    open(my $fh, ">>&=", $oldfh)
    

يعد الاقتصاد في مقابض الملفات مفيدًا أيضًا (بالإضافة إلى كونه اقتصاديًا) على سبيل المثال عندما يكون هناك شيء يعتمد على واصفات الملفات، مثل القفل باستخدام "flock". إذا قمت فقط بـ "open(my $A, ">>&", $B)"، فلن يكون لمقبض الملف $A نفس واصف الملف مثل $B، وبالتالي فإن flock($A) لن يقفل flock($B) ولا العكس. ولكن مع "open(my $A, ">>&=", $B)"، ستشترك مقابض الملفات في نفس واصف ملف النظام الأساسي.

لاحظ أنه في نسخ Perl الأقدم من 5.8.0، تستخدم Perl دالة fdopen(3) من مكتبة C القياسية لتنفيذ وظيفية "=". في العديد من أنظمة Unix، تفشل fdopen(3) عندما تتجاوز واصفات الملفات قيمة معينة، عادةً 255. بالنسبة لنسخ Perl 5.8.0 والأحدث، فإن PerlIO هو المبدئي (في أغلب الأحيان).

الاستخدام القديم
يصف هذا القسم طرق استدعاء "open" خارج نطاق أفضل الممارسات؛ قد تواجه هذه الاستخدامات في البرمجيات القديمة. لا تعتبر Perl استخدامها مهجورًا تمامًا، ولكن لا يُنصح بها في البرمجيات الجديدة، من أجل الوضوح وسهولة القراءة.
تحديد النمط واسم الملف كمعامل واحد
في شكلي الاستدعاء بوسيط واحد أو وسيطين، يجب دمج الوضع واسم الملف (بهذا الترتيب)، ويفضل الفصل بينهما بمسافة بيضاء. يمكنك -- ولكن لا ينبغي -- حذف الوضع في هذه الأشكال عندما يكون الوضع هو "<". من الآمن استخدام شكل الوسيطين لـ "open" إذا كان وسيط اسم الملف عبارة عن نص حرفي معروف.

 open(my $dbase, "+<dbase.mine")          # بالمثل
     or die "Can't open 'dbase.mine' for update: $!";
    

في صيغة المعاملين (والمعامل الواحد)، يؤدي فتح "<-" أو "-" إلى فتح STDIN ويؤدي فتح ">-" إلى فتح STDOUT.

يجب أن تفضل البرمجيات الجديدة صيغة المعاملات الثلاثة لـ "open" على هذه الصيغة القديمة. إن التصريح عن النمط واسم الملف كمعاملين متميزين يتجنب أي ارتباك بينهما.

إسناد مقبض ملف إلى كلمة مجردة (bareword)
الأسلوب القديم هو استخدام كلمة مجردة كمقبض للملف، مثل

    open(FH, "<", "input.txt")
       or die "Can't open < input.txt: $!";
    

بعد ذلك يمكنك استخدام "FH" كمقبض ملف، في "close FH" و "<FH>" وما إلى ذلك. لاحظ أنه متغير عام، لذا لا يُنصح بهذا الشكل عند التعامل مع مقابض ملفات أخرى غير تلك المدمجة في Perl (مثل STDOUT و STDIN). في الواقع، يعد استخدام كلمة مجردة (bareword) لمقبض الملف خطأ عند تعطيل ميزة "bareword_filehandles". تُعطل هذه الميزة آليًا عندما تكون في نطاق "use v5.36.0" أو أحدث.

كاختصار، يأخذ استدعاء المعامل الواحد اسم الملف من المتغير السلمي العام الذي له نفس اسم مقبض الملف ذو الكلمة المجردة:

    $ARTICLE = 100;
    open(ARTICLE)
        or die "Can't find article $ARTICLE: $!\n";
    

هنا يجب أن يكون $ARTICLE متغيرًا سلميًا عامًا في نفس الحزمة التي يوجد بها مقبض الملف - وليس متغيرًا مُصرحًا عنه بـ "my" أو "state".

اعتبارات أخرى
الإغلاق الآلي لمقبض الملف
سيُغلق مقبض الملف عندما يصل عدد مراجعة (reference count) إلى الصفر. إذا كان متغيرًا ذا نطاق معجمي مُصرحًا عنه بـ "my"، فإن ذلك يعني عادةً نهاية النطاق المحيط. ومع ذلك، فإن هذا الإغلاق الآلي لا يتحقق من الأخطاء، لذا من الأفضل إغلاق مقابض الملفات صراحةً، خاصة تلك المستخدمة للكتابة:

    close($handle)
       || warn "close failed: $!";
    
تفريغ الأنابيب الآلي
ستحاول Perl تفريغ جميع الملفات المفتوحة للإخراج قبل أي عملية قد تقوم بـ fork، ولكن قد لا يكون هذا مدعومًا في بعض المنصات (راجع perlport). لتكون آمنًا، قد تحتاج إلى ضبط $| (أو $AUTOFLUSH بالإنجليزية) أو استدعاء تابع "autoflush" الخاص بـ "IO::Handle" على أي مقابض مفتوحة.

في الأنظمة التي تدعم علامة "الإغلاق عند التنفيذ" (close-on-exec) على الملفات، سيُضبط هذا العلم لواصف الملف المفتوح حديثًا كما هو محدد بواسطة قيمة $^F. راجع "$^F" في perlvar.

يؤدي إغلاق أي مقبض ملف موجه عبر أنبوب إلى انتظار العملية الأب حتى ينتهي الابن، ثم يعيد قيمة الحالة في $? و "${^CHILD_ERROR_NATIVE}".

الإسناد المباشر مقابل الإسناد بالمرجع لمقابض الملفات
إذا كان FILEHANDLE -- المعامل الأول في استدعاء "open" -- متغيرًا سلميًا غير معرف (أو عنصر مصفوفة أو هاش)، فسيُنشأ مقبض ملف جديد آليًا (autovivified)، مما يعني أن المتغير يُسند إليه مرجع لمقبض ملف مجهول مخصص حديثًا. بخلاف ذلك، إذا كان FILEHANDLE تعبيرًا، فإن قيمته هي مقبض الملف الحقيقي. (يعتبر هذا مرجعًا رمزيًا، لذا يجب ألا يكون "use strict "refs"" قيد التنفيذ.)
المسافات البيضاء والمحارف الخاصة في معامل اسم الملف
اسم الملف الممرر إلى صيغ المعامل الواحد والمعاملين لـ "open" ستُحذف منه المسافات البيضاء البادئة واللاحقة وستُحترم محارف إعادة التوجيه العادية. هذه الخاصية، المعروفة باسم "الفتح السحري" (magic open)، يمكن استخدامها غالبًا لتحقيق نتائج جيدة. يمكن للمستخدم تحديد اسم ملف مثل "rsh cat file |"، أو يمكنك تغيير أسماء ملفات معينة حسب الحاجة:

    $filename =~ s/(.*\.gz)\s*$/gzip -dc < $1|/;
    open(my $fh, $filename)
        or die "Can't open $filename: $!";
    

استخدم صيغة المعاملات الثلاثة لفتح ملف يحتوي على محارف غريبة عشوائية،

    open(my $fh, "<", $file)
        || die "Can't open $file: $!";
    

خلاف ذلك، من الضروري حماية أي مسافات بيضاء بادئة أو لاحقة:

    $file =~ s#^(\s)#./$1#;
    open(my $fh, "< $file\0")
        || die "Can't open $file: $!";
    

(قد لا يعمل هذا على بعض أنظمة الملفات الغريبة). يجب على المرء أن يختار بعناية بين صيغة magic وصيغة المعاملات الثلاثة لـ "open":

    open(my $in, $ARGV[0]) || die "Can't open $ARGV[0]: $!";
    

ستسمح للمستخدم بتحديد معامل من الصيغة "rsh cat file |"، ولكنها لن تعمل على اسم ملف ينتهي بمسافة، بينما

    open(my $in, "<", $ARGV[0])
        || die "Can't open $ARGV[0]: $!";
    

سيكون لها بالضبط القيود المعاكسة. (ومع ذلك، تدعم بعض الصدفات بناء الجملة "perl your_program.pl <( rsh cat file )"، الذي ينتج اسم ملف يمكن فتحه بشكل طبيعي.)

إذا كنت تريد open(2) "حقيقيًا" لـ C، فيجب عليك استخدام دالة "sysopen"، التي لا تنطوي على مثل هذا السحر (ولكنها تستخدم أنماط ملفات مختلفة عن Perl "open"، التي تتوافق مع C fopen(3)). هذه طريقة أخرى لحماية أسماء ملفاتك من التفسير. على سبيل المثال:

    use IO::Handle;
    sysopen(my $fh, $path, O_RDWR|O_CREAT|O_EXCL)
        or die "Can't open $path: $!";
    $fh->autoflush(1);
    print $fh "stuff $$\n";
    seek($fh, 0, 0);
    print "File contains: ", readline($fh);
    

راجع "seek" للحصول على بعض التفاصيل حول الخلط بين القراءة والكتابة.

مسائل القابلية للنقل
راجع "open" في perlport.
تفتح دليلاً يسمى EXPR لمعالجته بواسطة "readdir"، و "telldir"، و "seekdir"، و "rewinddir"، و "closedir". تعيد true في حال النجاح. قد يكون DIRHANDLE تعبيرًا يمكن استخدام قيمته كمقبض دليل غير مباشر، عادةً ما يكون اسم مقبض الدليل الحقيقي. إذا كان DIRHANDLE متغيرًا سلميًا غير معرف (أو عنصر مصفوفة أو جدول تجزئة)، فيُعين للمتغير مرجع إلى مقبض دليل مجهول جديد؛ أي أنه يُنشأ حيًا تلقائيًا (autovivified). مقابض الأدلة هي نفس كائنات مقابض الملفات؛ لا يمكن فتح كائن إدخال/إخراج إلا كواحد من أنواع المقابض هذه في المرة الواحدة.

راجع المثال في "readdir".

ord EXPR
يعيد نقطة الترميز للمحرف الأول من EXPR. إذا كان EXPR سلسلة نصية فارغة، يعيد 0. إذا حُذف EXPR، يستخدم $_. (لاحظ محرف، وليس بايت.)

للعكس، راجع "chr". راجع perlunicode لمزيد عن يونيكود.

تقوم "our" بإنشاء اسم مستعار معجمي لمتغير حزمة (أي عام) بنفس الاسم في الحزمة الحالية لاستخدامه ضمن النطاق المعجمي الحالي.

تمتلك "our" نفس قواعد النطاق مثل "my" أو "state"، مما يعني أنها صالحة فقط ضمن نطاق معجمي. على عكس "my" و "state"، اللتين تصرحان عن متغيرات (معجمية) جديدة، فإن "our" تنشئ فقط اسمًا مستعارًا لمتغير موجود: متغير حزمة بنفس الاسم.

وهذا يعني أنه عند تفعيل "use strict 'vars'"، فإن "our" تسمح لك باستخدام متغير حزمة دون تأهيله باسم الحزمة، ولكن فقط ضمن النطاق المعجمي لتصريح "our". ينطبق هذا فورًا--حتى داخل نفس الجملة.

    package Foo;
    use v5.36;  # مما يتضمن "use strict;"
    $Foo::foo = 23;
    {
        our $foo;   # اسم مستعار لـ $Foo::foo
        print $foo; # يطبع 23
    }
    print $Foo::foo; # يطبع 23
    print $foo; # خطأ: يتطلب اسم حزمة صريح
    

يعمل هذا حتى لو لم يُستخدم متغير الحزمة من قبل، حيث تنبثق متغيرات الحزمة إلى الوجود عند أول استخدام لها.

    package Foo;
    use v5.36;
    our $foo = 23;   # تمامًا مثل $Foo::foo = 23
    print $Foo::foo; # يطبع 23
    

ولأن المتغير يصبح قانونيًا فورًا تحت "use strict 'vars'"، طالما أنه لا يوجد متغير بهذا الاسم موجود بالفعل في النطاق، يمكنك بعد ذلك مراجعة متغير الحزمة مرة أخرى حتى داخل نفس الجملة.

    package Foo;
    use v5.36;
    my  $foo = $foo; # خطأ، $foo غير مصرح عنه في الجانب الأيمن
    our $foo = $foo; # لا توجد أخطاء
    

إذا أُدرج أكثر من متغير واحد، فيجب وضع القائمة بين قوسين.

    our($bar, $baz);
    

مثل "my" و "state" و "local"، يمكن لـ "our" أن تعمل على متغير أينما ظهر في تعبير (باستثناء الاستيفاء داخل السلاسل النصية). لن ينطبق التصريح على الاستخدامات الإضافية لنفس المتغير حتى العبارة التالية. وهذا يعني أن الاستخدامات الإضافية لهذا المتغير ضمن نفس العبارة ستتصرف كما كانت قبل حدوث ذلك التصريح، باستثناء أنها ستظل تلبي strict 'vars' وتفسر ذلك المتغير كمتغير الحزمة الملقب حديثًا إذا لم يكن قد صُرح عنه بعد في ذلك النطاق.

    package main;
    my $x = 2;
    foo($x, our $x = $x + 1, $x); # تستقبل foo() قيم (2, 3, 2)
    foo($x, our $z = 5, $z);      # تستقبل foo() قيم (3, 5, 5)
    

يصرح تصريح "our" عن اسم مستعار لمتغير حزمة سيكون مرئيًا عبر كامل نطاقه المعجمي، حتى عبر حدود الحزم. يُحدد الحزمة التي يُدخل فيها المتغير عند نقطة التصريح، وليس عند نقطة الاستخدام. وهذا يعني أن السلوك التالي سارٍ:

    package Foo;
    our $bar;      # يصرح عن $Foo::bar لبقية النطاق المعجمي
    $bar = 20;
    package Bar;
    print $bar;    # يطبع 20، حيث يشير إلى $Foo::bar
    

يُسمح بتصاريح "our" متعددة بنفس الاسم في نفس النطاق المعجمي إذا كانت في حزم مختلفة. إذا كانت في نفس الحزمة، فستصدر Perl تحذيرات إذا طلبت ذلك، تمامًا مثل تصاريح "my" المتعددة. على عكس تصريح "my" ثانٍ، والذي سيربط الاسم بمتغير جديد، فإن تصريح "our" ثانٍ في نفس الحزمة، وفي نفس النطاق، هو مجرد تكرار غير ضروري.

    use warnings;
    package Foo;
    our $bar;      # يصرح عن $Foo::bar لبقية النطاق المعجمي
    $bar = 20;
    package Bar;
    our $bar = 30; # يصرح عن $Bar::bar لبقية النطاق المعجمي
    print $bar;    # يطبع 30
    our $bar;      # يصدر تحذيرًا ولكن ليس له أي تأثير آخر
    print $bar;    # لا يزال يطبع 30
    

قد يحتوي تصريح "our" أيضًا على قائمة سمات مرتبطة به.

لا تزال الدلالات الدقيقة وواجهة TYPE و ATTRS في طور التطور. يرتبط TYPE حاليًا باستخدام برجمة fields، وتُعالج السمات باستخدام برجمة attributes، أو، بدءًا من Perl 5.8.0، عبر وحدة Attribute::Handlers أيضًا. راجع "المتغيرات الخاصة عبر my()" في perlsub لمزيد من التفاصيل.

لاحظ أنه مع القائمة الموضوعة بين قوسين، يمكن استخدام "undef" كعنصر نائب وهمي، على سبيل المثال لتخطي إسناد القيم الأولية:

    our ( undef, $min, $hour ) = localtime;
    

تنشئ "our" لقبًا محدد النطاق معجميًا لمتغير الحزمة الذي يحمل نفس الاسم، وعلى هذا النحو تختلف عن "use vars"، التي تسمح باستخدام اسم غير مؤهل فقط داخل الحزمة المتأثرة، دون مراعاة للنطاقات.

تأخذ LIST من القيم وتحولها إلى سلسلة نصية باستخدام القواعد المحددة بواسطة TEMPLATE. السلسلة الناتجة هي دمج للقيم المحولة. عادةً ما تبدو كل قيمة محولة مثل تمثيلها على مستوى الآلة. على سبيل المثال، في الآلات ذات 32 بت، قد يُمثل العدد الصحيح بتسلسل من بايتات، والتي ستُقدم في Perl كسلسلة نصية طولها 's محارف.

راجع perlpacktut لمقدمة حول هذه الدالة.

TEMPLATE هو تسلسل من المحارف التي تحدد ترتيب ونوع القيم، كما يلي:

    a  سلسلة نصية ببيانات ثنائية عشوائية، ستُحشى بأصفار (null).
    A  سلسلة نصية (ASCII)، ستُحشى بمسافات.
    Z  سلسلة نصية منتهية بصفار (ASCIZ)، ستُحشى بأصفار.
    b  سلسلة بتات (ترتيب بتات تصاعدي داخل كل بايت،
       مثل vec()).
    B  سلسلة بتات (ترتيب بتات تنازلي داخل كل بايت).
    h  سلسلة ست عشرية (النيبل المنخفض أولاً).
    H  سلسلة ست عشرية (النيبل المرتفع أولاً).
    c  قيمة محرف (8-بت) مُشار.
    C  قيمة محرف (أوكتيت) غير مُشار.
    W  قيمة محرف غير مُشار (يمكن أن تكون أكبر من 255).
    s  قيمة قصيرة (16-بت) مُشارة.
    S  قيمة قصيرة غير مُشارة.
    l  قيمة طويلة (32-بت) مُشارة.
    L  قيمة طويلة غير مُشارة.
    q  قيمة رباعية (64-بت) مُشارة.
    Q  قيمة رباعية غير مُشارة.
         (القيم الرباعية متاحة فقط إذا كان نظامك يدعم قيم الأعداد
          الصحيحة 64-بت _و_ إذا جُمعت Perl لتدعمها.
          تطلق استثناءً بخلاف ذلك.)
    i  قيمة عدد صحيح مُشار.
    I  قيمة عدد صحيح غير مُشار.
         (هذا 'العدد الصحيح' بعرض 32 بت على الأقل. حجمه الدقيق
          يعتمد على ما يسميه مصرف C المحلي 'int'.)
    n  قيمة قصيرة غير مُشارة (16-بت) بترتيب "الشبكة" (الطرفية الكبيرة).
    N  قيمة طويلة غير مُشارة (32-بت) بترتيب "الشبكة" (الطرفية الكبيرة).
    v  قيمة قصيرة غير مُشارة (16-بت) بترتيب "VAX" (الطرفية الصغيرة).
    V  قيمة طويلة غير مُشارة (32-بت) بترتيب "VAX" (الطرفية الصغيرة).
    j  قيمة عدد صحيح مُشار داخلية لـ Perl (IV).
    J  قيمة عدد صحيح غير مُشار داخلية لـ Perl (UV).
    f  عدد فاصل عائم بدقة مفردة بالتنسيق الأصلي.
    d  عدد فاصل عائم بدقة مزدوجة بالتنسيق الأصلي.
    F  قيمة فاصل عائم داخلية لـ Perl (NV) بالتنسيق الأصلي
    D  عدد فاصل عائم بدقة double طويلة بالتنسيق الأصلي.
         (الـ doubles الطويلة متاحة فقط إذا كان نظامك يدعمها.
          تطلق استثناءً بخلاف ذلك. لاحظ وجود تنسيقات مختلفة لها.)
    p  مؤشر إلى سلسلة نصية منتهية بصفار.
    P  مؤشر إلى بنية (سلسلة نصية ثابتة الطول).
    u  سلسلة نصية مرمزة بـ uuencode.
    U  رقم محرف يونيكود. يرمز إلى محرف في وضع المحارف
       وإلى UTF-8 (أو UTF-EBCDIC في منصات EBCDIC) في وضع البايت.
       أيضًا في منصات EBCDIC، سيكون رقم المحرف هو قيمة EBCDIC الأصلية
       لأرقام المحارف الأقل من 256. يسمح هذا لمعظم البرامج التي
       تستخدم هذه الميزة بعدم الاهتمام بنوع المنصة التي تعمل عليها.
    w  عدد صحيح مضغوط بـ BER (ليس ASN.1 BER، انظر perlpacktut
       للتفاصيل). تمثل بايتاته عددًا صحيحًا غير مُشار في الأساس 128،
       الرقم الأكثر أهمية أولاً، بأقل عدد ممكن من الأرقام.
       البت الثامن (البت العالي) يُضبط في كل بايت ما عدا الأخير.
    x  بايت صفري (يُعرف أيضًا باسم ASCII NUL، "\000"، chr(0))
    X  الرجوع بايت واحد للخلف.
    @  الحشو بالأصفار أو الاقتطاع إلى موضع مطلق، محسوبًا من
       بداية المجموعة () الأعمق.
    .  الحشو بالأصفار أو الاقتطاع إلى موضع مطلق محدد بواسطة القيمة.
    (  بداية مجموعة ().
    

قد يتبع واحد أو أكثر من المعدلات أدناه اختياريًا أحرفًا معينة في TEMPLATE (يسرد العمود الثاني الأحرف التي يكون المعدل صالحًا لها):

    !   sSlLiI     يفرض الأحجام الأصلية (short, long, int) بدلاً
                   من الأحجام الثابتة (16-/32-بت).
    !   xX         يجعل x و X يعملان كأوامر محاذاة.
    !   nNvV       يعامل الأعداد الصحيحة كموقعة بدلاً من غير موقعة.
    !   @.         يحدد الموضع كإزاحة بايت في التمثيل الداخلي
                   للسلسلة المحزومة. فعال ولكنه خطر.
    >   sSiIlLqQ   يفرض ترتيب البايتات big-endian على النوع.
        jJfFdDpP   (النهاية الكبيرة تلمس البنية.)
    <   sSiIlLqQ   يفرض ترتيب البايتات little-endian على النوع.
        jJfFdDpP   (النهاية الصغيرة تلمس البنية.)
    

يمكن أيضًا استخدام المعدلين ">" و "<" على مجموعات "()" لفرض ترتيب بايت معين على جميع المكونات في تلك المجموعة، بما في ذلك جميع مجموعاتها الفرعية.

تنطبق القواعد التالية:

قد يتبع كل حرف اختياريًا رقم يشير إلى عدد التكرار. يمكن اختياريًا وضع عدد تكرار رقمي بين قوسين مربعين، كما في "pack("C[80]", @arr)". يستهلك عدد التكرار هذا العدد من القيم من LIST عند استخدامه مع جميع أنواع التنسيق بخلاف "a"، و "A"، و "Z"، و "b"، و "B"، و "h"، و "H"، و "@"، و "."، و "x"، و "X"، و "P"، حيث يعني شيئًا آخر موصوفًا أدناه. إن تزويد "*" لعدد التكرار بدلاً من رقم يعني استخدام جميع العناصر المتبقية، باستثناء:
  • "@"، و "x"، و "X"، حيث يعادل 0.
  • <.>، حيث يعني بالنسبة لبداية السلسلة النصية.
  • "u"، حيث يعادل 1 (أو 45، وهو ما يعادلها هنا).

يمكن استبدال عدد التكرار الرقمي بحرف قالب موضوع بين قوسين مربعين لاستخدام طول البايت المحزوم للقالب الموضوع بين قوسين لعدد التكرار.

على سبيل المثال، يتخطى القالب "x[L]" عدد البايتات الموجودة في long محزوم، والقالب "$t X[$t] $t" يفك حزم ضعف ما يفكه $t (عند توسيع المتغير). إذا كان القالب الموجود بين القوسين يحتوي على أوامر محاذاة (مثل "x![d]")، فإن طوله المحزوم يُحسب كما لو كانت بداية القالب لها أقصى محاذاة ممكنة.

عند استخدامه مع "Z"، فإن "*" كعدد تكرار يضمن إضافة بايت null لاحق، لذا فإن السلسلة الناتجة تكون دائمًا أطول ببايت واحد من طول البايت للعنصر نفسه.

عند استخدامه مع "@"، يمثل عدد التكرار إزاحة من بداية مجموعة "()" الأكثر عمقاً.

عند استخدامه مع "."، يحدد عدد التكرار موضع البداية لحساب إزاحة القيمة كما يلي:

  • إذا كان عداد التكرار 0، فإنه يكون نسبيًا للموضع الحالي.
  • إذا كان عدد التكرار هو "*"، فإن الإزاحة تكون نسبية لبداية السلسلة المحزمة (packed).
  • وإذا كان عددًا صحيحًا n، فإن الإزاحة تكون نسبية لبداية المجموعة "( )" الأعمق رقم n، أو لبداية السلسلة إذا كان n أكبر من مستوى المجموعة.

يُفسر عدد التكرار لـ "u" كأقصى عدد من البايتات لتشفيرها لكل سطر مخرجات، مع استبدال 0 و 1 و 2 بالقيمة 45. يجب ألا يتجاوز عدد التكرار 65.

  • تستهلك الأنواع "a" و "A" و "Z" قيمة واحدة فقط، لكنها تحزمها كسلسلة بطول العدد المحدد، مع الحشو بالأصفار (nulls) أو المسافات حسب الحاجة. عند فك التحزيم، يزيل النوع "A" المسافات البيضاء والأصفار اللاحقة، ويزيل النوع "Z" كل شيء بعد أول صفر، بينما يعيد النوع "a" البيانات دون أي إزالة على الإطلاق.

    إذا كانت القيمة المطلوب حزمها طويلة جدًا، تُقتطع النتيجة. إذا كانت طويلة جدًا مع توفير عداد صريح، فإن "Z" تحزم فقط "$count-1" بايت، يتبعها بايت صفري. وبالتالي فإن "Z" تحزم دائمًا صفراً لاحقاً، إلا عندما يكون العداد 0.

  • وبالمثل، تقوم صيغتي "b" و "B" بتعبئة سلسلة بطول (Aqs من البتات. يولد كل تنسيق من هذا النوع 1 بت من النتيجة. وعادة ما يتبعها عدد التكرارات مثل "B8" أو "B64".

    تعتمد كل بت من النتيجة على البت الأقل أهمية للمحرف المدخل المقابل، أي على "ord($char)%2". وبشكل خاص، تولّد المحارف "0" و "1" البتات 0 و 1، كما تفعل المحارف "\000" و "\001".

    بدءاً من بداية سلسلة المدخلات، تُحوّل كل مجموعة مكونة من 8 محارف إلى محرف واحد من المخرجات. مع التنسيق "b"، يحدد المحرف الأول من المجموعة المكونة من 8 البت الأقل أهمية للمحرف؛ ومع التنسيق "B"، يحدد البت الأكثر أهمية.

    إذا لم يكن طول سلسلة المدخلات قابلاً للقسمة على 8 بالتساوي، يُحزم الباقي كما لو كانت سلسلة المدخلات محشوة بمحارف صفرية في نهايتها. وبالمثل أثناء فك التحزيم، تُتجاهل البتات "الزائدة".

    إذا كانت سلسلة المدخلات أطول من اللازم، تُتجاهل المحارف المتبقية.

    يستخدم الرمز "*" لعدد التكرار جميع محارف حقل المدخلات. عند فك التحزيم، تُحوّل البتات إلى سلسلة من الأصفار 0 والآحاد 1.

  • تحزم التنسيقات "h" و "H" سلسلة بطول تلك النيبلات (nybbles) (مجموعات من 4 بتات، يمكن تمثيلها كأرقام ست عشرية، "0".."9" و "a".."f").

    لكل تنسيق من هذا القبيل، يولّد "pack" أربعة بتات من النتيجة. بالنسبة للمحارف غير الأبجدية، تعتمد النتيجة على الـ 4 بتات الأقل أهمية للمحرف المدخل، أي على "ord($char)%16". وبشكل خاص، تولّد المحارف "0" و "1" النيبلات 0 و 1، كما تفعل البايتات "\000" و "\001". بالنسبة للمحارف "a".."f" و "A".."F"، تكون النتيجة متوافقة مع الأرقام الست عشرية المعتادة، بحيث يولّد كل من "a" و "A" النيبل "0xA==10". استخدم فقط هذه المحارف الست عشرية المحددة مع هذا التنسيق.

    بدءاً من بداية القالب لـ "pack"، يتم تحويل كل زوج من المحارف إلى محرف واحد من المخرجات. مع التنسيق "h"، يحدد المحرف الأول من الزوج النيبل الأقل أهمية لمحرف المخرجات؛ ومع التنسيق "H"، فإنه يحدد النيبل الأكثر أهمية.

    إذا لم يكن طول سلسلة المدخلات زوجياً، فإنه يتصرف كما لو كان محشواً بمحرف صفري في نهايته. وبالمثل، تُتجاهل النيبلات "الزائدة" أثناء فك التحزيم.

    إذا كانت سلسلة المدخلات أطول من اللازم، تُتجاهل المحارف الزائدة.

    يستخدم الرمز "*" لعدد التكرار جميع محارف حقل المدخلات. بالنسبة لـ "unpack"، تُحوّل النيبلات إلى سلسلة من الأرقام الست عشرية.

  • يحزم التنسيق "p" مؤشراً لسلسلة تنتهي بصفر (null-terminated). أنت مسؤول عن ضمان أن السلسلة ليست قيمة مؤقتة، حيث يمكن أن يتم إلغاء تخصيصها قبل أن تتاح لك فرصة استخدام النتيجة المحزمة. يحزم التنسيق "P" مؤشراً لبنية (structure) بالحجم المحدد بواسطة الطول. يتم إنشاء مؤشر فارغ (null pointer) إذا كانت القيمة المقابلة لـ "p" أو "P" هي "undef"؛ وبالمثل مع "unpack"، حيث يُفك المؤشر الفارغ إلى "undef".

    إذا كان نظامك يحتوي على حجم مؤشر غريب -بمعنى أن المؤشر ليس بحجم int ولا بحجم long- فقد لا يكون من الممكن حزم أو فك تحزيم المؤشرات بترتيب البايتات النهاية الكبيرة (big-endian) أو النهاية الصغيرة (little-endian). محاولة القيام بذلك تثير استثناءً.

  • يسمح محرف القالب "/" بحزم وفك حزم تسلسل من العناصر حيث تحتوي البنية المحزومة على عداد عناصر محزوم يتبعه العناصر المحزومة نفسها. هذا مفيد عندما تكون البنية التي تفك حزمها قد رمزت الأحجام أو أعداد التكرار لبعض حقولها داخل البنية نفسها كحقول منفصلة.

    بالنسبة لـ "pack"، تكتب length-item"/"sequence-item، ويصف الـ length-item كيفية حزم قيمة الطول. التنسيقات التي من المرجح أن تكون أكثر فائدة هي تلك الخاصة بحزم الأعداد الصحيحة مثل "n" لسلاسل Java، و "w" لـ ASN.1 أو SNMP، و "N" لـ Sun XDR.

    بالنسبة لـ "pack"، قد يكون لـ sequence-item عداد تكرار، وفي هذه الحالة يُستخدم الحد الأدنى منه ومن عدد العناصر المتاحة كوسيط لـ length-item. إذا لم يكن له عداد تكرار أو استخدم '*'، يُستخدم عدد العناصر المتاحة.

    بالنسبة لـ "unpack"، تُستخدم رصة داخلية من معطيات الأعداد الصحيحة التي فُك حزمها حتى الآن. تكتب "/"sequence-item ويُحصل على عدد التكرار عن طريق سحب (popping) العنصر الأخير من الرصة. يجب ألا يكون لـ sequence-item عدد تكرار.

    إذا كان sequence-item يشير إلى نوع سلسلة ("A" أو "a" أو "Z")، فإن length-item هو طول السلسلة، وليس عدد السلاسل. مع عدد تكرار صريح لـ pack، تُعدل السلسلة المحزومة لتناسب ذلك الطول. على سبيل المثال:

        هذا الكود:                              يعطي هذه النتيجة:
        unpack("W/a", "\004Gurusamy")           ("Guru")
        unpack("a3/A A*", "007 Bond  J ")       (" Bond", "J")
        unpack("a3 x2 /A A*", "007: Bond, J.")  ("Bond, J", ".")
        pack("n/a* w/a", "hi,", "world")        "\000\003hi,\005world"
        pack("a/W2", ord("a") .. ord("z"))      "2ab"
        

    لا يُعاد length-item صراحة من "unpack".

    تزويد عدد لحرف تنسيق length-item مفيد فقط مع "A" أو "a" أو "Z". قد يؤدي الحزم باستخدام length-item من نوع "a" أو "Z" إلى إدخال محارف "\000"، والتي لا تعتبرها Perl قانونية في السلاسل الرقمية.

  • قد تُتبع أنواع الأعداد الصحيحة "s" و "S" و "l" و "L" بمعدل "!" لتحديد الأعداد القصيرة (shorts) أو الطويلة (longs) الأصلية (native). كما هو موضح في المثال أعلاه، فإن "l" المجردة تعني 32 بت بالضبط، رغم أن الـ "long" الأصلي كما يراه مترجم C المحلي قد يكون أكبر. هذه مشكلة أساسًا على المنصات ذات 64 بت. يمكنك معرفة ما إذا كان استخدام "!" يحدث أي فرق بهذه الطريقة:

        printf "format s is %d, s! is %d\n",
            length pack("s"), length pack("s!");
        printf "format l is %d, l! is %d\n",
            length pack("l"), length pack("l!");
        

    يُسمح أيضًا بـ "i!" و "I!"، ولكن فقط من أجل الاكتمال: فهما متطابقان مع "i" و "I".

    الأحجام الفعلية (بالبايت) للأعداد القصيرة (shorts) والأعداد الصحيحة (ints) والطويلة (longs) والطويلة جدًا (long longs) الأصلية على المنصة التي بنيت عليها Perl متاحة أيضًا من سطر الأوامر:

        $ perl -V:{short,int,long{,long}}size
        shortsize='2';
        intsize='4';
        longsize='4';
        longlongsize='8';
        

    أو برمجياً عبر وحدة "Config":

        use Config;
        print $Config{shortsize},    "\n";
        print $Config{intsize},      "\n";
        print $Config{longsize},     "\n";
        print $Config{longlongsize}, "\n";
        

    $Config{longlongsize} غير معرفة في الأنظمة التي لا تدعم long long.

  • تنسيقات الأعداد الصحيحة "s" و "S" و "i" و "I" و "l" و "L" و "j" و "J" هي بطبيعتها غير محمولة بين المعالجات وأنظمة التشغيل لأنها تتبع ترتيب البايتات والنهايات (endianness) الأصلية. على سبيل المثال، عدد صحيح مكون من 4 بايتات 0x12345678 (305419896 عشري) سيُرتب أصليًا (يُرتب في سجلات وحدة المعالجة المركزية ويُعالج بواسطتها) إلى بايتات كـ

        0x12 0x34 0x56 0x78  # النهاية الكبرى (big-endian)
        0x78 0x56 0x34 0x12  # النهاية الصغرى (little-endian)
        

    بشكل أساسي، معالجات Intel و VAX هي من نوع النهاية الصغرى (little-endian)، بينما الجميع الآخرون، بما في ذلك Motorola m68k/88k و PPC و Sparc و HP PA و Power و Cray، هم من نوع النهاية الكبرى (big-endian). يمكن لـ Alpha و MIPS أن يكونا أيًا منهما: استخدمتها Digital/Compaq في وضع النهاية الصغرى، بينما تستخدمها SGI/Cray في وضع النهاية الكبرى.

    الاسمان big-endian و little-endian هما إشارات هزلية لعادات أكل البيض لدى الليليبوتيين (Lilliputians) والبلفوسكوديين (Blefuscudians) من هجاء جوناثان سويفت الكلاسيكي، رحلات جوليفر. دخل هذا المصطلح لغة الحاسوب عبر ورقة "حول الحروب المقدسة والتماس السلام" بقلم داني كوهين، USC/ISI IEN 137، بتاريخ 1 أبريل 1980.

    قد تحتوي بعض الأنظمة على ترتيب بايتات أغرب مثل

        0x56 0x78 0x12 0x34
        0x34 0x12 0x78 0x56
        

    تسمى هذه النهاية الوسطى (mid-endian أو middle-endian)، أو النهاية المختلطة (mixed-endian)، أو فقط غريبة.

    يمكنك تحديد نهاية نظامك باستخدام هذه التعويذة:

        printf("%#02x ", $_) for unpack("W*", pack("L", 0x12345678));
        

    ترتيب البايتات (byteorder) على المنصة التي بنيت عليها Perl متاح أيضًا عبر Config:

        use Config;
        print "$Config{byteorder}\n";
        

    أو من سطر الأوامر:

        $ perl -V:byteorder
        

    ترتيبات البايتات (Byteorders) من نوع "1234" و "12345678" هي ذات ترتيب صغير؛ أما "4321" و "87654321" فهي ذات ترتيب كبير. الأنظمة ذات البنى المتعددة ستحتوي على "ffff"، مما يشير إلى أن المعلومات الساكنة لا تعمل، ويجب استخدام الاستقصاء في وقت التشغيل.

    بالنسبة للأعداد الصحيحة المحزومة بشكل محمول، استخدم إما التنسيقات "n" و "N" و "v" و "V" أو استخدم معدلات ">" و "<" الموضحة أدناه مباشرة. انظر أيضًا perlport.

  • أيضًا أرقام الفاصلة العائمة لها نهاية. عادةً (ولكن ليس دائمًا) يتفق هذا مع نهاية الأعداد الصحيحة. على الرغم من أن معظم المنصات هذه الأيام تستخدم التنسيق الثنائي IEEE 754، إلا أن هناك اختلافات، خاصة إذا كانت الـ doubles الطويلة معنية. يمكنك رؤية متغيرات "Config" مثل "doublekind" و "longdblkind" (وأيضًا "doublesize" و "longdblsize"): قيم "kind" هي تعدادات (enums)، على عكس "byteorder".

    من ناحية المحمولية، ربما يكون الخيار الأفضل هو الالتزام بـ IEEE 754 64-بت doubles، وبنهاية متفق عليها. وهناك احتمال آخر وهو تنسيق "%a" لـ "printf".

  • بدءًا من Perl 5.10.0، يمكن أن تتبع تنسيقات الأعداد الصحيحة والفاصلة العائمة، بالإضافة إلى تنسيقات "p" و "P" ومجموعات "()"، بمعدلات الطرفية (endianness) ">" أو "<" لفرض ترتيب البايتات الكبير أو الصغير على التوالي. تعتبر هذه المعدلات مفيدة بشكل خاص نظرًا لأن "n" و "N" و "v" و "V" لا تغطي الأعداد الصحيحة المُشارة، أو الأعداد الصحيحة 64-بت، أو قيم الفاصلة العائمة.

    فيما يلي بعض الاعتبارات التي يجب وضعها في الاعتبار عند استخدام معدل النهاية:

  • يعمل تبادل الأعداد الصحيحة المُشارة بين المنصات المختلفة فقط عندما تخزنها جميع المنصات بنفس التنسيق. تخزن معظم المنصات الأعداد الصحيحة المُشارة في تدوين المتمم لاثنين (two's-complement)، لذا عادةً لا يمثل هذا مشكلة.
  • لا يمكن استخدام معدلات ">" أو "<" على تنسيقات الفاصلة العائمة إلا في آلات النهاية الكبرى أو الصغرى. بخلاف ذلك، فإن محاولة استخدامها تثير استثناءً.
  • إن فرض ترتيب البايتات الكبير (big-endian) أو الصغير (little-endian) على قيم الفاصلة العائمة لتبادل البيانات لا يعمل إلا إذا كانت جميع المنصات تستخدم نفس التمثيل الثنائي مثل IEEE للفاصلة العائمة. وحتى لو كانت جميع المنصات تستخدم IEEE، فقد تظل هناك اختلافات دقيقة. إن القدرة على استخدام ">" أو "<" على قيم الفاصلة العائمة قد تكون مفيدة، ولكنها خطيرة أيضًا إذا لم تكن تعلم بالضبط ما تفعله. إنها ليست طريقة عامة لتخزين قيم الفاصلة العائمة بشكل محمول.
  • عند استخدام ">" أو "<" على مجموعة "()"، فإن هذا يؤثر على جميع الأنواع داخل المجموعة التي تقبل معدلات ترتيب البايتات، بما في ذلك جميع المجموعات الفرعية. ويُتجاهل بصمت لجميع الأنواع الأخرى. لا يُسمح لك بتجاوز ترتيب البايتات داخل مجموعة تحتوي بالفعل على لاحقة معدل ترتيب البايتات.
  • الأرقام الحقيقية (floats و doubles) تكون بتنسيق الآلة الأصلي فقط. نظرًا لتعدد تنسيقات الفاصلة العائمة وعدم وجود تمثيل قياسي "للشبكة" لها، لم يُنشأ أي مرفق للتبادل. وهذا يعني أن بيانات الفاصلة العائمة المحزومة المكتوبة على آلة واحدة قد لا تكون قابلة للقراءة على آلة أخرى، حتى لو كانت كلتاهما تستخدمان حسابات الفاصلة العائمة IEEE (لأن نهاية تمثيل الذاكرة ليس جزءًا من مواصفات IEEE). انظر أيضًا perlport.

    إذا كنت تعلم بالضبط ما تفعله، يمكنك استخدام المغيرات ">" أو "<" لفرض ترتيب البايتات الكبير أو الصغير على قيم الفاصلة العائمة.

    لأن Perl تستخدم doubles (أو doubles طويلة، إذا ضُبطت كذلك) داخليًا لجميع الحسابات الرقمية، فإن التحويل من double إلى float ومن ثم إلى double مرة أخرى يؤدي لفقدان الدقة، لذا فإن "unpack("f", pack("f", $foo)") لن تساوي $foo بشكل عام.

  • يمكن للدالتين pack و unpack العمل في وضعين: وضع المحارف (وضع "C0") حيث تُعالج السلسلة المحزومة محرفًا بمحرف، ووضع بايتات UTF-8 (وضع "U0") حيث تُعالج السلسلة المحزومة في شكل Unicode المرمز بترميز UTF-8 على أساس بايت ببايت. وضع المحارف هو الوضع المبدئي ما لم تبدأ سلسلة التنسيق بـ "U". يمكنك دائمًا تبديل الوضع في منتصف التنسيق باستخدام "C0" أو "U0" صراحةً في التنسيق. يظل هذا الوضع ساري المفعول حتى تغيير الوضع التالي، أو حتى نهاية مجموعة "()" التي ينطبق عليها (مباشرة).

    استخدام "C0" للحصول على محارف Unicode بينما يُستخدم "U0" للحصول على بايتات غير تابعة لـ Unicode ليس واضحًا بالضرورة. ربما يكون الخيار الأول فقط هو ما تريده:

        $ perl -CS -E 'say "\x{3B1}\x{3C9}"' |
          perl -CS -ne 'printf "%v04X\n", $_ for unpack("C0A*", $_)'
        03B1.03C9
        $ perl -CS -E 'say "\x{3B1}\x{3C9}"' |
          perl -CS -ne 'printf "%v02X\n", $_ for unpack("U0A*", $_)'
        CE.B1.CF.89
        $ perl -CS -E 'say "\x{3B1}\x{3C9}"' |
          perl -C0 -ne 'printf "%v02X\n", $_ for unpack("C0A*", $_)'
        CE.B1.CF.89
        $ perl -CS -E 'say "\x{3B1}\x{3C9}"' |
          perl -C0 -ne 'printf "%v02X\n", $_ for unpack("U0A*", $_)'
        C3.8E.C2.B1.C3.8F.C2.89
        

    توضح تلك الأمثلة أيضًا أنه لا ينبغي محاولة استخدام pack/unpack كبديل للوحدة Encode.

  • يجب عليك القيام بأي محاذاة أو حشو بنفسك عن طريق إدراج، على سبيل المثال، ما يكفي من محارف "x" أثناء الحزم. لا توجد طريقة لـ pack و unpack لمعرفة أين تذهب المحارف أو من أين تأتي، لذا فهما يعالجان مخرجاتهما ومدخلاتهما كـ تسلسلات مسطحة من المحارف.
  • مجموعة "()" هي قالب فرعي (sub-TEMPLATE) محصور بين قوسين. قد تأخذ المجموعة عدد تكرار إما كلاحقة، أو بالنسبة لـ unpack، عبر محرف القالب "/" أيضًا. ضمن كل تكرار للمجموعة، يبدأ تحديد الموضع باستخدام "@" من 0 مرة أخرى. لذلك، فإن نتيجة

        # ملاحظة: علامات اقتباس مفردة حول سلسلة القالب لمنع
        # استكمال المصفوفة لـ ‎@1، ‎@2، ‎@3
        pack('@1A((@2A)@3A)', qw[X Y Z])
        

    هي السلسلة "\0X\0\0YZ".

  • يقبل كل من x و X المعدل "!" ليعملا كأوامر محاذاة: حيث يقفزان للأمام أو للخلف إلى أقرب موضع محاذى لمضاعفات عدد "count" من المحارف. على سبيل المثال، لحزم (pack) أو فك حزم (unpack) بنية C مثل

        struct {
            char   c;    /* one signed, 8-bit character */
            double d;
            char   cc[2];
        }
        

    قد يحتاج المرء إلى استخدام القالب "c x![d] d c[2]". يفترض هذا وجوب محاذاة الأعداد من النوع double إلى حجم الـ double.

    بالنسبة لأوامر المحاذاة، فإن قيمة "count" التي تساوي 0 تكافئ القيمة 1؛ كلاهما لا ينفذ أي عملية.

  • تقبل "n" و "N" و "v" و "V" المغير "!" لتمثيل الأعداد الصحيحة الموقعة ذات 16/32 بت بترتيب البايتات الكبير/الصغير. يكون هذا محمولاً فقط عندما تستخدم جميع المنصات التي تتشارك البيانات المكدومة (packed) نفس التمثيل الثنائي للأعداد الصحيحة الموقعة؛ على سبيل المثال، عندما تستخدم جميع المنصات تمثيل المتمم الثنائي (two's-complement).
  • يمكن تضمين التعليقات في القالب (TEMPLATE) باستخدام "#" حتى نهاية السطر. يمكن للمسافات البيضاء أن تفصل بين أكواد الحزم، ولكن يجب أن تتبع المعدلات وأعداد التكرار الكود مباشرة. إن تقسيم القوالب المعقدة إلى مكونات فردية سطرًا بسطر، مع تذييلها بملاحظات مناسبة، يمكن أن يحسن مقروئية وصيانة تنسيقات pack/unpack بنفس القدر الذي يفعله "/x" لمطابقات الأنماط المعقدة.
  • إذا تطلب القالب (TEMPLATE) وسائط أكثر مما أُعطي لـ pack، تفترض pack وجود وسائط "" إضافية. إذا تطلب القالب وسائط أقل مما أُعطي، تُتجاهل الوسائط الزائدة.
  • إن محاولة كدم قيم الفاصلة العائمة الخاصة "Inf" و "NaN" (اللانهاية، بما في ذلك السالبة، وليس رقمًا) في قيم صحيحة مكدومة (مثل "L") هو خطأ فادح. والسبب في ذلك هو ببساطة عدم وجود أي مقابلة منطقية لهذه القيم الخاصة في الأعداد الصحيحة.

أمثلة:

    $foo = pack("WWWW",65,66,67,68);
    # foo eq "ABCD"
    $foo = pack("W4",65,66,67,68);
    # نفس الشيء
    $foo = pack("W4",0x24b6,0x24b7,0x24b8,0x24b9);
    # نفس الشيء مع أحرف Unicode المحاطة بدوائر.
    $foo = pack("U4",0x24b6,0x24b7,0x24b8,0x24b9);
    # نفس الشيء مع أحرف Unicode المحاطة بدوائر. لن تحصل على
    # بايتات UTF-8 لأن الحرف U في بداية التنسيق تسبب في
    # التحويل إلى وضع U0، لذا يتم ضم بايتات UTF-8 في
    # محارف
    $foo = pack("C0U4",0x24b6,0x24b7,0x24b8,0x24b9);
    # foo eq "\xe2\x92\xb6\xe2\x92\xb7\xe2\x92\xb8\xe2\x92\xb9"
    # هذا هو ترميز UTF-8 للسلسلة في المثال
    # السابق
    $foo = pack("ccxxcc",65,66,67,68);
    # foo eq "AB\0\0CD"
    # ملاحظة: الأمثلة أعلاه التي تتضمن "W" و "c" صحيحة
    # فقط في أنظمة ASCII والأنظمة المشتقة منها مثل ISO Latin 1
    # و UTF-8. في أنظمة EBCDIC، سيكون المثال الأول
    #      $foo = pack("WWWW",193,194,195,196);
    $foo = pack("s2",1,2);
    # "\001\000\002\000" في النهاية الصغرى
    # "\000\001\000\002" في النهاية الكبرى
    $foo = pack("a4","abcd","x","y","z");
    # "abcd"
    $foo = pack("aaaa","abcd","x","y","z");
    # "axyz"
    $foo = pack("a14","abcdefg");
    # "abcdefg\0\0\0\0\0\0\0"
    $foo = pack("i9pl", gmtime);
    # بنية tm حقيقية (في نظامي على الأقل)
    $utmp_template = "Z8 Z8 Z16 L";
    $utmp = pack($utmp_template, @utmp1);
    # بنية utmp (BSDish)
    @utmp2 = unpack($utmp_template, $utmp);
    # "@utmp1" eq "@utmp2"
    sub bintodec {
        unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
    }
    $foo = pack('sx2l', 12, 34);
    # short 12، بايتان صفر حشو، long 34
    $bar = pack('s@4l', 12, 34);
    # short 12، ملء بالأصفار حتى الموضع 4، long 34
    # $foo eq $bar
    $baz = pack('s.l', 12, 4, 34);
    # short 12، ملء بالأصفار حتى الموضع 4، long 34
    $foo = pack('nN', 42, 4711);
    # حزم أعداد صحيحة غير موقعة بـ 16 و 32 بت بترتيب النهاية الكبرى
    $foo = pack('S>L>', 42, 4711);
    # نفس الشيء تمامًا
    $foo = pack('s<l<', -42, 4711);
    # حزم أعداد صحيحة موقعة بـ 16 و 32 بت بترتيب النهاية الصغرى
    $foo = pack('(sl)<', -42, 4711);
    # نفس الشيء تمامًا

يمكن استخدام القالب نفسه بشكل عام أيضًا في unpack.

يعلن عن الكتلة (BLOCK) أو بقية وحدة التصريف كونهما في مساحة التسمية المعطاة. نطاق إعلان الحزمة (package) هو إما كتلة الكود المزودة، أو في حال غياب الكتلة، من الإعلان نفسه حتى نهاية النطاق الحالي (الكتلة المحيطة، أو الملف، أو "eval"). أي أن الصيغ التي لا تحتوي على كتلة تكون عاملة حتى نهاية النطاق الحالي، تمامًا مثل العوامل "my" و "state" و "our". جميع المعرفات الديناميكية غير المؤهلة في هذا النطاق ستكون في مساحة التسمية المعطاة، إلا إذا تم تجاوزها بإعلان "package" آخر أو عندما تكون أحد المعرفات الخاصة التي تتأهل إلى "main::"، مثل "STDOUT" و "ARGV" و "ENV" ومتغيرات الترقيم.

يؤثر بيان الحزمة (package) على المتغيرات الديناميكية فقط، بما في ذلك تلك التي استخدمت "local" عليها، ولكن ليس المتغيرات ذات النطاق المعجمي، التي تُنشأ باستخدام "my" أو "state" أو "our". عادةً ما يكون هو الإعلان الأول في ملف مضمن بواسطة "require" أو "use". يمكنك الانتقال إلى حزمة في أكثر من مكان، لأن هذا يحدد فقط جدول الرموز المبدئي الذي يستخدمه المصرف لبقية تلك الكتلة. يمكنك الإشارة إلى المعرفات في حزم أخرى غير الحزمة الحالية ببادئة المعرف باسم الحزمة ونقطتين مزدوجتين، كما في $SomePack::var أو "ThatPack::INPUT_HANDLE". إذا حُذف اسم الحزمة، تُفترض الحزمة "main". أي أن $::sail يكافئ $main::sail (وكذلك "$main'sail"، التي لا تزال تُرى في الأكواد القديمة، ومعظمها من Perl 4).

إذا تم توفير VERSION، يقوم "package" بضبط المتغير $VERSION في مساحة التسمية المعطاة لكائن إصدار بـ VERSION المقدم. يجب أن يكون VERSION رقم إصدار بنمط "strict" كما هو محدد بواسطة وحدة الإصدار: رقم عشري موجب (صحيح أو كسر عشري) بدون أس، أو سلسلة v منقطعة عشرية تبدأ بحرف 'v' وتتكون من ثلاثة مكونات على الأقل. يجب ضبط $VERSION مرة واحدة فقط لكل حزمة.

انظر "Packages" في perlmod لمزيد من المعلومات حول الحزم، والوحدات، والأصناف. انظر perlsub لمسائل النطاق الأخرى.

__PACKAGE__
رمز خاص يعيد اسم الحزمة التي ورد فيها.
__CLASS__
عند استدعائه داخل method، أو موقع مشابه، مثل تعبير تهيئة حقل، يعيد هذا الرمز اسم صنف النسخة المستدعية. هو في الأساس يكافئ ref($self) باستثناء أنه يمكن استخدامه إضافيًا في مهيئ حقل للوصول إلى توابع الصنف، قبل اكتمال بناء النسخة.

    use feature 'class';
    class Example1 {
        field $f = __CLASS__->default_f;
        sub default_f { 10 }
    }
    

في صنف أساسي، ستكون هذه القيمة هي نفسها __PACKAGE__. يمكن رؤية الفرق عند بناء صنف فرعي؛ حيث سيعطي اسم صنف النسخة التي يجري بناؤها، بدلاً من مجرد اسم الحزمة التي ينتمي إليها الكود الفعلي.

    class Example2 :isa(Example1) {
        sub default_f { 20 }
    }
    my $obj = Example2->new;
    # The $f field now has the value 20
    
يفتح زوجًا من الأنابيب المتصلة مثل استدعاء النظام المقابل. لاحظ أنه إذا قمت بإعداد حلقة من العمليات الأنبوبية، فقد يحدث استعصاء (deadlock) ما لم تكن حذرًا جدًا. بالإضافة إلى ذلك، لاحظ أن أنابيب Perl تستخدم التخزين المؤقت للمدخلات والمخرجات، لذا قد تحتاج إلى ضبط $| لتفريغ WRITEHANDLE بعد كل أمر، اعتمادًا على التطبيق.

يعيد قيمة صواب عند النجاح.

انظر IPC::Open2 و IPC::Open3 و "Bidirectional Communication with Another Process" في perlipc لأمثلة على مثل هذه الأشياء.

في الأنظمة التي تدعم علامة الإغلاق عند التنفيذ (close-on-exec) على الملفات، تُضبط هذه العلامة على جميع واصفات الملفات المفتوحة حديثًا التي تكون قيم fileno الخاصة بها أعلى من القيمة الحالية لـ $^F (افتراضيًا 2 لـ STDERR). انظر "$^F" في perlvar.

pop ARRAY
يزيل ويعيد العنصر الأخير من المصفوفة، ويقصر المصفوفة بمقدار عنصر واحد.

    my @arr  = ('cat', 'dog', 'mouse');
    my $item = pop(@arr); # 'mouse'
    # @arr is now ('cat', 'dog')
    

يعيد undef إذا كانت المصفوفة فارغة.

ملاحظة: قد يعيد pop أيضًا undef إذا كان العنصر الأخير في المصفوفة هو undef.

    my @arr  = ('one', 'two', undef);
    my $item = pop(@arr); # undef
    

إذا حُذفت المصفوفة (ARRAY)، يعمل pop على مصفوفة @ARGV في البرنامج الرئيس، ولكن على مصفوفة @_ في البرامج الفرعية. سيعمل pop على مصفوفة @ARGV في كتل eval STRING و BEGIN {} و INIT {} و CHECK {}.

بدءًا من Perl 5.14، سمحت ميزة تجريبية لـ pop بأخذ تعبير سلمي (scalar). اعتبرت هذه التجربة غير ناجحة، وأزيلت اعتبارًا من Perl 5.24.

pos SCALAR
يعيد إزاحة المكان الذي توقف عنده آخر بحث m//g للمتغير المعني (تُستخدم $_ عندما لا يُحدد المتغير). هذه الإزاحة تكون بالمحارف ما لم يكن موجّه (pragma)‏ use bytes (الذي لم يعد موصى به) قيد التشغيل، وفي هذه الحالة تكون الإزاحة بالبايتات. لاحظ أن 0 هو إزاحة مطابقة صالحة. تشير undef إلى إعادة ضبط موضع البحث (عادةً بسبب فشل المطابقة، ولكن يمكن أن يكون أيضًا لأنه لم يتم إجراء أي مطابقة بعد على المتغير السلمي).

يصل "pos" مباشرة إلى الموقع الذي يستخدمه محرك التعبيرات النمطية لتخزين الإزاحة، لذا فإن التعيين لـ "pos" سيغير تلك الإزاحة، وبالتالي سيؤثر أيضًا على توكيد العرض الصفر "\G" في التعبيرات النمطية. يحدث كلا التأثيرين للمطابقة التالية، لذا لا يمكنك التأثير على الموضع باستخدام "pos" أثناء المطابقة الحالية، كما في "(?{pos() = 5})" أو "s//pos() = 5/e".

يؤدي ضبط pos أيضًا إلى إعادة ضبط علامة المطابقة بطول صفري، الموصوفة تحت "Repeated Patterns Matching a Zero-length Substring" في perlre.

بما أن مطابقة "m//gc" الفاشلة لا تعيد ضبط الإزاحة، فإن القيمة الراجعة من "pos" لن تتغير أيضًا في هذه الحالة. انظر perlre و perlop.

print FILEHANDLE LIST
print FILEHANDLE
print LIST
يطبع سلسلة أو قائمة من السلاسل. يعيد قيمة صواب إذا نجح. قد يكون FILEHANDLE متغيرًا سلميًا يحتوي على اسم واصف الملف أو مرجعًا له، مما يقدم مستوى واحدًا من المداورة (indirection). (ملاحظة: إذا كان FILEHANDLE متغيرًا وكان الرمز التالي تعبيرًا، فقد يساء تفسيره كعامل ما لم تضع + بينهما أو تضع أقواسًا حول الوسائط). إذا حُذف FILEHANDLE، يطبع إلى آخر واصف مخرجات تم اختياره (انظر select). إذا حُذفت القائمة (LIST)، يطبع $_ إلى واصف المخرجات المختار حاليًا. لاستخدام FILEHANDLE وحده لطباعة محتوى $_ إليه، يجب استخدام واصف ملف مجرد (bareword) مثل FH، وليس واصفًا غير مباشر مثل $fh. لضبط واصف المخرجات المبدئي إلى شيء آخر غير STDOUT، استخدم عملية select.

تُطبع القيمة الحالية لـ $, (إن وجدت) بين كل عنصر من عناصر القائمة (LIST). وتُطبع القيمة الحالية لـ "$\" (إن وجدت) بعد طباعة القائمة بالكامل. ولأن print تأخذ قائمة، فإن أي شيء في القائمة يُقيم في سياق القائمة، بما في ذلك أي دوال فرعية تمرر قوائمها الراجعة إلى "print". احذر من إتباع الكلمة المفتاحية print بقوس أيسر ما لم تكن تريد أن يقوم القوس الأيمن المقابل بإنهاء وسائط print؛ ضع أقواسًا حول جميع الوسائط (أو أدخل "+"، لكن ذلك لا يبدو جيدًا).

إذا كنت تخزن المقابض في مصفوفة أو مفرمة، أو بشكل عام متى استخدمت أي تعبير أكثر تعقيدًا من مقبض مجرد أو متغير سلمي بسيط غير مفهرس لاسترجاعه، سيتعين عليك استخدام كتلة تعيد قيمة مقبض الملف بدلاً من ذلك، وفي هذه الحالة لا يجوز حذف القائمة (LIST):

    print { $files[$i] } "stuff\n";
    print { $OK ? *STDOUT : *STDERR } "stuff\n";
    

ستؤدي الطباعة إلى أنبوب أو مقبس مغلق إلى توليد إشارة SIGPIPE. انظر perlipc لمزيد من المعلومات حول معالجة الإشارات.

printf FILEHANDLE FORMAT, LIST
printf FILEHANDLE
printf FORMAT, LIST
تكافئ print FILEHANDLE sprintf(FORMAT, LIST)، باستثناء أنه لا يتم إلحاق $\ (فاصل سجل المخرجات). يتم في الواقع تحليل FORMAT والقائمة LIST كقائمة واحدة. ستُفسر الوسيطة الأولى في القائمة على أنها تنسيق printf. هذا يعني أن printf(@_) ستستخدم $_[0] كتنسيق. انظر sprintf لشرح لوسيطة التنسيق. إذا كان موجّه use locale (بما في ذلك use locale ':not_characters') قيد التشغيل واستُدعيت POSIX::setlocale، فإن المحرف المستخدم كفاصل عشري في أرقام الفاصلة العائمة المنسقة يتأثر بإعدادات المكان LC_NUMERIC. انظر perllocale و POSIX.

لأسباب تاريخية، إذا حذفت القائمة، تُستخدم $_ كتنسيق؛ لاستخدام FILEHANDLE بدون قائمة، يجب استخدام واصف ملف مجرد مثل FH، وليس واصفًا غير مباشر مثل $fh. ومع ذلك، نادرًا ما سيفعل هذا ما تريد؛ إذا كانت $_ تحتوي على أكواد تنسيق، فسيتم استبدالها بسلل فارغة وسيصدر تحذير إذا كانت التحذيرات مفعلة. استخدم فقط print إذا كنت تريد طباعة محتويات $_.

لا تقع في فخ استخدام "printf" عندما يكون استخدام "print" البسيط كافيًا. إن "print" أكثر كفاءة وأقل عرضة للخطأ.

prototype FUNCTION
تعيد النموذج الأولي للدالة كسلسلة (أو undef إذا لم يكن للدالة نموذج أولي). FUNCTION هي مرجع للدالة، أو اسمها، التي تريد استعادة نموذجها الأولي. إذا حُذفت FUNCTION، تُستخدم $_.

إذا كانت FUNCTION سلسلة تبدأ بـ "CORE::"، يُؤخذ الباقي كاسم لدالة مدمجة في Perl. إذا كانت وسائط الدالة المدمجة لا يمكن التعبير عنها بشكل كافٍ بواسطة نموذج أولي (مثل "system")، تعيد "prototype" القيمة "undef"، لأن الدالة المدمجة لا تتصرف حقًا مثل دالة Perl. خلاف ذلك، تُعاد السلسلة التي تصف النموذج الأولي المكافئ.

تضيف عنصرًا واحدًا أو أكثر إلى نهاية المصفوفة.

        my @animals = ("cat");
        push(@animals, "mouse"); # ("cat", "mouse")
        my @colors = ("red");
        push(@colors, ("blue", "green")); # ("red", "blue", "green")
    

تعيد عدد العناصر في المصفوفة بعد اكتمال عملية push.

        my $color_count = push(@colors, ("yellow", "purple"));
        say "There are $color_count colors in the updated array";
    

بدءًا من Perl 5.14، سمحت ميزة تجريبية لـ push بأخذ تعبير سلمي. اعتبرت هذه التجربة غير ناجحة، وأزيلت اعتبارًا من Perl 5.24.

عوامل اقتباس معممة. انظر "Quote-Like Operators" في perlop.
اقتباس شبيه بالتعابير النمطية. انظر "Regexp Quote-Like Operators" في perlop.
quotemeta EXPR
يعيد قيمة EXPR مع إضافة شرطة مائلة خلفية لجميع محارف ASCII غير "الكلمية". (بمعنى أن كل محارف ASCII التي لا تطابق "/[A-Za-z_0-9]/" ستُسبق بشرطة مائلة خلفية في السلسلة المعادة، بغض النظر عن أي إعدادات محلية.) هذه هي الدالة الداخلية التي تنفذ هروب "\Q" في السلاسل المقتبسة اقتباساً مزدوجاً. (انظر أدناه لمعرفة السلوك مع نقاط ترميز غير ASCII.)

إذا حُذفت EXPR، تُستخدم $_.

الدافع وراء ذلك هو جعل جميع المحارف في EXPR تطابق ذواتها الحرفية. وإلا فإن أي محارف معالجة (metacharacters) فيها قد تحفز سلوكيات المطابقة "السحرية" الخاصة بها. المحارف التي طُبقت عليها هذه الدالة يقال إنها "مقتبسة" أو "مهربة" (escaped).

تعد quotemeta (و "\Q" ... "\E") مفيدة عند إقحام السلاسل في التعابير النمطية، لأن المتغير المقحم سيُعتبر تعبيراً نمطياً مصغراً بشكل مبدئي. على سبيل المثال:

    my $sentence = 'The quick brown fox jumped over the lazy dog';
    my $substring = 'quick.*?fox';
    $sentence =~ s{$substring}{big bad wolf};
    

سيؤدي هذا إلى جعل $sentence تصبح 'The big bad wolf jumped over...'.

من ناحية أخرى:

    my $sentence = 'The quick brown fox jumped over the lazy dog';
    my $substring = 'quick.*?fox';
    $sentence =~ s{\Q$substring\E}{big bad wolf};
    

أو:

    my $sentence = 'The quick brown fox jumped over the lazy dog';
    my $substring = 'quick.*?fox';
    my $quoted_substring = quotemeta($substring);
    $sentence =~ s{$quoted_substring}{big bad wolf};
    

سيترك كلاهما الجملة كما هي. عادةً، عند قبول إدخال سلسلة حرفية من المستخدم، يجب استخدام quotemeta أو \Q.

احذر من أنك إذا وضعت مائلات خلفية حرفية (تلك التي ليست داخل متغيرات مستبدلة) بين \Q و \E، فإن استبدال المائلة الخلفية بنمط الاقتباس المزدوج قد يؤدي إلى نتائج مربكة. إذا كنت بحاجة لاستخدام مائلات خلفية حرفية ضمن \Q...\E، فاستشر "Gory details of parsing quoted constructs" في perlop.

نظرًا لأن نتيجة "\Q STRING \E" تحتوي على جميع المحارف الواصفة مقتبسة، فلا توجد طريقة لإدراج محرف $ أو @ حرفي داخل زوج \Q\E. إذا حُمي بواسطة \، فسيتم اقتباس $ ليصبح "\\\$"؛ وإن لم يكن كذلك، فسيُفسر على أنه بداية متغير سلمي مستبدل.

في إصدار Perl v5.14، يتم اقتباس جميع المحارف غير التابعة لـ ASCII في السلاسل غير المرمزة بترميز UTF-8، ولكن لا يتم اقتباسها في سلاسل UTF-8.

بدءًا من Perl v5.16، اعتمدت Perl استراتيجية محددة من Unicode لاقتباس المحارف غير التابعة لـ ASCII؛ وبقي اقتباس محارف ASCII دون تغيير.

أيضًا لم يتغير اقتباس السلاسل غير التابعة لـ UTF-8 عندما تكون خارج نطاق use feature 'unicode_strings'، وهو اقتباس جميع المحارف في نطاق Latin1 العلوي. يوفر هذا توافقية كاملة مع الإصدارات السابقة للبرامج القديمة التي لا تستخدم Unicode. (لاحظ أن unicode_strings يتم تفعيلها آليًا ضمن نطاق use v5.12 أو أحدث).

ضمن نطاق use locale، يتم اقتباس جميع نقاط ترميز Latin1 غير التابعة لـ ASCII سواء كانت السلسلة مرمزة بترميز UTF-8 أم لا. كما ذُكر أعلاه، لا يؤثر المكان (locale) على اقتباس المحارف في نطاق ASCII. يحمي هذا من الأماكن التي تُعتبر فيها محارف مثل "|" محارف كلمات.

خلاف ذلك، تقتبس Perl المحارف غير التابعة لـ ASCII باستخدام تكييف من Unicode (انظر <https://www.unicode.org/reports/tr31/>). نقاط الترميز الوحيدة التي يتم اقتباسها هي تلك التي تمتلك أيًا من خصائص Unicode التالية: Pattern_Syntax، أو Pattern_White_Space، أو White_Space، أو Default_Ignorable_Code_Point، أو General_Category=Control.

من بين هذه الخصائص، الخاصيتان المهمتان هما Pattern_Syntax و Pattern_White_Space. لقد وضعهما Unicode لهذا الغرض تحديدًا المتمثل في تحديد المحارف التي يجب اقتباسها في نمط التعبير النمطي. لا يوجد أي محرف يمكن أن يكون في معرف يمتلك هذه الخصائص.

تعد Perl بأننا إذا أضفنا يومًا ما محارف واصفة لأنماط التعبيرات النمطية إلى الاثني عشر المعرفة بالفعل (\ | ( ) [ { ^ $ * + ? .)، فإننا سنستخدم فقط تلك التي تمتلك خاصية Pattern_Syntax. كما تعد Perl بأننا إذا أضفنا يومًا ما محارف تُعتبر مسافات بيضاء في التعبيرات النمطية (المتأثرة حاليًا بشكل أساسي بـ "/x")، فستمتلك جميعها خاصية Pattern_White_Space.

يعد Unicode بأن مجموعة نقاط الترميز التي تمتلك هاتين الخاصيتين لن تتغير أبدًا، لذا فإن الشيء الذي لم يُقتبس في v5.16 لن يحتاج أبدًا إلى الاقتباس في أي إصدار مستقبلي من Perl. (لم يتم في الواقع تعيين محارف لجميع نقاط الترميز التي تطابق Pattern_Syntax؛ لذا هناك مجال للنمو، ولكن يتم اقتباسها سواء كانت معينة أم لا. وبالطبع، لن تستخدم Perl أبدًا نقطة ترميز غير معينة كمحرف واصف فعلي).

يتم اقتباس المحارف التي تمتلك الخصائص الثلاث الأخرى لتعزيز مقروئية التعبير النمطي وليس لأنها تحتاج فعليًا إلى الاقتباس لأغراض التعبير النمطي (من المحتمل ألا يمكن تمييز المحارف التي تمتلك خاصية White_Space على الصفحة أو الشاشة عن تلك التي تمتلك خاصية Pattern_White_Space؛ والخاصيتان الأخريان تحتويان على محارف غير قابلة للطباعة).

rand EXPR
تعيد رقمًا كسريًا عشوائيًا أكبر من أو يساوي 0 و أقل من قيمة EXPR. (يجب أن تكون EXPR موجبة.) إذا حُذفت EXPR، تُستخدم القيمة 1.

    my $num1 = rand();        # فاصلة عائمة عشوائية على الأقل 0 وأقل من 1
    my $num2 = rand(7);       # فاصلة عائمة عشوائية على الأقل 0 وأقل من 7
    my $num3 = int(rand(10)); # عدد صحيح عشوائي على الأقل 0 وأقل من 10
    

ملاحظات:

  • استدعاء "rand" يستدعي آليًا "srand" ما لم يكن srand قد استدعي بالفعل.
  • حاليًا EXPR التي قيمتها 0 تُعامل كحالة خاصة على أنها 1. لم يكن هذا موثقًا قبل Perl 5.8.0 وهو عرضة للتغيير في إصدارات Perl المستقبلية.
  • بدءًا من Perl v5.20.0 يستخدم rand() مولد الأرقام العشوائية الزائفة "drand48" لتوليد أرقام عشوائية. وكمولد أرقام عشوائية زائفة (PRNG)، يجب أن يكون "drand48" كافيًا لمعظم الاحتياجات غير المتعلقة بالتعمية. إذا كنت بحاجة إلى أرقام عشوائية تعموية، فراجع CPAN للبحث عن بدائل آمنة تعمويًا.
الأمان:
"rand" ليس آمنًا تعمويًا. يجب ألا تعتمد عليه في المواقف الحساسة أمنيًا. حتى وقت كتابة هذا، يقدم عدد من وحدات CPAN التابعة لجهات خارجية مولدات أرقام عشوائية يقصد مؤلفوها أن تكون آمنة تعمويًا، بما في ذلك:
  • Crypt::URandom
  • Crypt::PRNG
تحاول قراءة محارف بطول LENGTH من البيانات إلى المتغير SCALAR من ممسك الملف FILEHANDLE المحدد. تُعيد عدد المحارف التي قُرئت فعلياً، أو 0 عند نهاية الملف، أو undef إذا حدث خطأ (وفي الحالة الأخيرة يُضبط $! أيضاً). سيتم زيادة حجم SCALAR أو تقليصه بحيث يكون آخر محرف قُرئ فعلياً هو آخر محرف في المتغير السلمي بعد القراءة.

يمكن تحديد OFFSET لوضع البيانات المقروءة في مكان ما في السلسلة غير البداية. تحدد الإزاحة OFFSET السالبة الموضع بعدد من المحارف بالعد تنازلياً من نهاية السلسلة. أما الإزاحة OFFSET الموجبة الأكبر من طول SCALAR فتؤدي إلى حشو السلسلة إلى الحجم المطلوب ببايتات "\0" قبل إلحاق نتيجة القراءة.

    open(my $FH, "<", "input.txt") or die("تعذر فتح الملف: $!");
    my $buf = "";
    my $num = 0;
    # قراءة 32 بايت
    $num = read($FH, $buf, 32);
    # قراءة 16 بايت في الموقع 1024 من $buf
    $num = read($FH, $buf, 16, 1024);
    

نُفذ الاستدعاء بدلالة إما دالة مكتبة fread(3) الخاصة بـ Perl أو دالة المكتبة الأصلية لنظامك، عبر طبقات PerlIO المطبقة على المقبض. للحصول على استدعاء نظام read(2) حقيقي، انظر sysread.

لاحظ الـ محارف: اعتمادًا على حالة مقبض الملف، تُقرأ إما بايتات (8-بت) أو محارف. مبدئيًا، تعمل جميع مقابض الملفات على البايتات، ولكن على سبيل المثال إذا فُتح مقبض الملف باستخدام طبقة الإدخال/الإخراج ":utf8" (انظر "open"، والموجه open)، فستعمل عملية الإدخال/الإخراج على محارف يونيكود مرمزة بـ UTF8، وليس بايتات. وينطبق الشيء نفسه على طبقة ":encoding": في هذه الحالة يمكن قراءة أي محارف تقريبًا.

تُعيد مدخل الدليل التالي لدليل وُصل بواسطة "opendir". إذا استُخدمت في سياق قائمة، تُعيد جميع الإدخالات المتبقية في الدليل. إذا لم يعد هناك المزيد من الإدخالات، تُعيد القيمة غير المعرفة في سياق المتغير السلمي والقائمة الفارغة في سياق القائمة.

إذا كنت تخطط لاختبار الملف للقيم الراجعة من "readdir"، فمن الأفضل إلحاق الدليل المعني في البداية. وإلا، ولأننا لم نقم بـ "chdir" إلى هناك، فسيتم اختبار الملف الخاطئ.

    opendir(my $dh, $some_dir) || die "Can't opendir $some_dir: $!";
    my @dots = grep { /^\./ && -f "$some_dir/$_" } readdir($dh);
    closedir $dh;
    

بدءًا من Perl 5.12 يمكنك استخدام "readdir" مجردة في حلقة "while"، والتي ستعين $_ في كل تكرار. إذا استُخدم إما تعبير "readdir" أو تعيين صريح لتعبير "readdir" لمتغير سلمي كشرط لـ "while"/"for"، فإن الشرط يختبر في الواقع تعريف قيمة التعبير، وليس قيمته المنطقية العادية.

    opendir(my $dh, $some_dir) || die "Can't open $some_dir: $!";
    while (readdir $dh) {
        print "$some_dir/$_\n";
    }
    closedir $dh;
    

لتجنب إرباك المستخدمين المحتملين لشفرتك الذين يشغلون إصدارات سابقة من Perl بإخفاقات غامضة، ضع هذا النوع من الأشياء في قمة ملفك للإشارة إلى أن شفرتك ستعمل فقط على نسخ Perl الحديثة:

    use v5.12; # لكي تُسند readdir إلى $_ في اختبار while المنفرد
    
readline EXPR
تقرأ من ممسك الملف الذي يوجد typeglob الخاص به في EXPR (أو من *ARGV إذا لم يتم توفير EXPR). في سياق المتغير السلمي، يقرأ كل استدعاء ويعيد السطر التالي حتى يتم الوصول إلى نهاية الملف، وعندها يُعيد الاستدعاء اللاحق "undef". في سياق القائمة، تقرأ حتى يتم الوصول إلى نهاية الملف وتعيد قائمة من الأسطر. لاحظ أن مفهوم "السطر" المستخدم هنا هو كل ما قد حددته بـ $/ (أو $INPUT_RECORD_SEPARATOR بالإنجليزية). انظر "$/" في perlvar.

عندما يُضبط $/ على "undef"، وعندما تكون "readline" في سياق المتغير السلمي (أي وضع ارتشاف الملف)، وعند قراءة ملف فارغ، فإنها تعيد '' في المرة الأولى، متبوعة بـ "undef" لاحقاً.

هذه هي الدالة الداخلية التي تُنفذ عامل "<EXPR>"، ولكن يمكنك استخدامها مباشرة. يُناقش عامل "<EXPR>" بمزيد من التفصيل في "عوامل الإدخال/الإخراج" في perlop.

    my $line = <STDIN>;
    my $line = readline(STDIN);    # نفس الشيء
    

إذا واجهت "readline" خطأ في نظام التشغيل، فسيُضبط $! برسالة الخطأ المقابلة. قد يكون من المفيد التحقق من $! عندما تقرأ من مقابض ملفات لا تثق بها، مثل tty أو مقبس. يستخدم المثال التالي شكل العامل لـ "readline" ويتوقف (dies) إذا كانت النتيجة غير معرفة.

    while ( ! eof($fh) ) {
        defined( $_ = readline $fh ) or die "readline failed: $!";
        ...
    }
    

لاحظ أنه لا يمكنك معالجة أخطاء "readline" بهذه الطريقة مع مقبض الملف "ARGV". في هذه الحالة، يتعين عليك فتح كل عنصر من @ARGV بنفسك لأن "eof" يعالج "ARGV" بشكل مختلف.

    foreach my $arg (@ARGV) {
        open(my $fh, $arg) or warn "Can't open $arg: $!";
        while ( ! eof($fh) ) {
            defined( $_ = readline $fh )
                or die "readline failed for $arg: $!";
            ...
        }
    }
    

مثل العامل "<EXPR>"، إذا استُخدم تعبير "readline" كشرط لحلقة "while" أو "for"، فسيُسند ضمنيًا إلى $_. إذا استُخدم تعبير "readline" أو إسناد صريح لتعبير "readline" إلى قيمة سلمية كشرط "while"/"for"، فإن الشرط يختبر في الواقع حالة التعريف (definedness) لقيمة التعبير، وليس قيمته المنطقية المعتادة.

readlink EXPR
تُعيد قيمة الوصلة الرمزية، إذا كانت الوصلات الرمزية مدعومة. إذا لم تكن كذلك، تثير استثناءً. إذا كان هناك خطأ في النظام، تُعيد القيمة غير المعرفة وتضبط $! (رقم الخطأ). إذا حُذفت EXPR، تستخدم $_.

مشاكل النقلية: "readlink" في perlport.

readpipe EXPR
يُنفذ EXPR كأمر نظام. ويُعاد المخرج القياسي المجمع للأمر. في سياق سلمي، يعود كسلسلة نصية واحدة (يُحتمل أن تكون متعددة الأسطر). وفي سياق قائمة، يعيد قائمة من الأسطر (حسب تعريفك للأسطر باستخدام $/ (أو $INPUT_RECORD_SEPARATOR بالإنجليزية)). هذه هي الدالة الداخلية التي تنفذ عامل "qx/EXPR/"، ولكن يمكنك استخدامها مباشرة. يُناقش عامل "qx/EXPR/" بمزيد من التفصيل في ""qx/STRING/"" في perlop. إذا حُذف EXPR، تُستخدم $_.
يستقبل رسالة على مقبس (socket). يحاول استقبال عدد LENGTH من محارف البيانات في المتغير SCALAR من مقبض ملف SOCKET المحدد. سيتم توسيع أو تقليص SCALAR لتناسب الطول المقروء فعليًا. يأخذ نفس الأعلام التي يأخذها استدعاء النظام الذي يحمل نفس الاسم. يعيد عنوان المرسل إذا كان بروتوكول SOCKET يدعم ذلك؛ وإلا فيعيد سلسلة نصية فارغة. في حال حدوث خطأ، يعيد القيمة غير المعرفة. هذا الاستدعاء مُنفذ فعليًا بواسطة استدعاء النظام recvfrom(2). انظر "UDP: Message Passing" في perlipc للحصول على أمثلة.

لاحظ أنه إذا تم وسم المقبس بـ ":utf8"، فإن "recv" ستثير استثناءً. تُقدم طبقة :encoding(...) ضمنياً طبقة ":utf8". انظر "binmode".

redo LABEL
redo EXPR
يعيد أمر "redo" تشغيل كتلة الحلقة دون تقييم الشرط مرة أخرى. لا يتم تنفيذ كتلة "continue"، إن وجدت. إذا حُذفت LABEL، يشير الأمر إلى الحلقة المحيطة الأكثر عمقاً. يتيح شكل "redo EXPR"، المتوفر بدءاً من Perl 5.18.0، حساب اسم اللصيقة في وقت التشغيل، وهو مطابق خلاف ذلك لـ "redo LABEL". تستخدم البرامج التي تريد الكذب على نفسها بشأن ما تم إدخاله للتو هذا الأمر عادةً:

    # مفرغ تعليقات باسكال بسيط
    # (تحذير: يفترض عدم وجود { أو } في السلاسل النصية)
    LINE: while (<STDIN>) {
        while (s|({.*}.*){.*}|$1 |) {}
        s|{.*}| |;
        if (s|{.*| |) {
            my $front = $_;
            while (<STDIN>) {
                if (/}/) {  # end of comment?
                    s|^|$front\{|;
                    redo LINE;
                }
            }
        }
        print;
    }
    

لا يمكن لـ "redo" إرجاع قيمة من كتلة تُرجع قيمة عادةً، مثل "eval {}"، أو "sub {}"، أو "do {}". سوف تنفذ سلوك التحكم في التدفق الخاص بها، مما يمنع أي قيمة إرجاع. لا ينبغي استخدامها للخروج من عملية "grep" أو "map".

لاحظ أن الكتلة بمفردها مطابقة دلالياً لحلقة تُنفذ مرة واحدة. وبالتالي فإن "redo" داخل مثل هذه الكتلة ستحولها فعلياً إلى بنية تكرارية.

انظر أيضًا "continue" لتوضيح كيفية عمل "last" و "next" و "redo".

على عكس معظم العوامل المسمى، فإن لهذا العامل نفس أسبقية التعيين. كما أنه معفى من قاعدة "يبدو وكأنه دالة"، لذا فإن "redo ("foo")."bar"" ستجعل "bar" جزءاً من الوسيط لـ "redo".

ref EXPR
تفحص قيمة EXPR، متوقعةً أن تكون مرجعاً، وتُعيد سلسلة نصية تعطي معلومات حول المرجع ونوع المشار إليه. إذا لم يتم تحديد EXPR، سيتم استخدام $_.

إذا لم يكن المعامل مرجعاً، فسيتم إرجاع سلسلة فارغة. لن يتم إرجاع سلسلة فارغة إلا في هذه الحالة. غالباً ما تكون "ref" مفيدة لمجرد اختبار ما إذا كانت القيمة مرجعاً، وهو ما يمكن فعله بمقارنة النتيجة بالسلسلة الفارغة. من الأخطاء الشائعة استخدام نتيجة "ref" مباشرة كقيمة منطقية: هذا يخطئ لأن القيمة 0 (وهي خطأ) يمكن أن تُعاد من أجل المرجع.

إذا كان المعامل مرجعًا لكائن مُبارك (blessed object)، فسيُعاد اسم الفئة (class) التي بورك فيها المرجع. لا تهتم "ref" بالنوع الفيزيائي للمرجع؛ فللمباركة الأولوية على هذه المخاوف. احذر من أن المقارنة الدقيقة لنتائج "ref" مقابل اسم فئة لا تؤدي اختبار عضوية الفئة: فاعضاء الفئة يشملون أيضًا الكائنات المباركة في فئات فرعية، والتي ستعيد "ref" لها اسم الفئة الفرعية. احذر أيضًا من أن أسماء الفئات قد تتعارض مع أسماء الأنواع المضمنة (الموصوفة أدناه). استخدم تابع "isa" لاختبار عضوية الفئة لاسم فئة أو كائن مبارك، بعد التأكد من أنه أحد هذه الأشياء. بدلاً من ذلك، يمكن لعامل "isa" اختبار عضوية الفئة دون التحقق من حالة المباركة أولاً.

إذا كان المعامل مرجعًا لكائن غير مبارك، فإن القيمة المعادة تشير إلى نوع الكائن. إذا لم يكن المرجع غير المبارك سلميًا، فستكون القيمة المعادة واحدة من السلاسل النصية "ARRAY" أو "HASH" أو "CODE" أو "FORMAT" أو "IO"، مما يشير فقط إلى نوع الكائن. إذا كان المرجع غير المبارك سلميًا، فستكون القيمة المعادة واحدة من السلاسل النصية "SCALAR" أو "VSTRING" أو "REF" أو "GLOB" أو "LVALUE" أو "REGEXP"، اعتمادًا على نوع القيمة التي يحملها السلم حاليًا. ولكن لاحظ أن قيم "qr//" السلمية تُنشأ مباركة بالفعل، لذا فمن المرجح أن يعيد "ref qr/.../" القيمة "Regexp". احذر من أن أسماء الأنواع المضمنة هذه يمكن استخدامها أيضًا كأسماء فئات، لذا فإن إعادة "ref" لأحد هذه الأسماء لا يشير بشكل قاطع إلى أن المرجع هو من النوع الذي يشير إليه الاسم.

الغموض بين أسماء الأنواع المضمنة وأسماء الفئات قد يحد من فائدة "ref"، ولكن من الناحية العملية، نادراً ما تحدث مثل هذه التعارضات ما لم يتم تصميمها عن قصد. للحصول على معلومات غير غامضة، استخدم "blessed" في builtin للحصول على معلومات حول المباركة، و "reftype" في builtin للحصول على معلومات حول الأنواع الفيزيائية. ولكن احذر من أن النوع الفيزيائي الذي تعيده "reftype" لا يشير إلى كيفية استخدام الكائن المبارك، وعمليات إلغاء المرجعية (dereference) المناسبة لكائن ما (سواء للوصول إلى الهيكل المبارك مباشرةً، أو عبر تحميل زائد) ستكون موصوفة في وثائق فئة الكائن.

انظر أيضاً perlref و perlobj.

تغير اسم ملف؛ وسيتم طمس أي ملف NEWNAME موجود. تُعيد true للنجاح؛ وعند الإخفاق تُعيد false وتضبط $!.

يختلف سلوك هذه الدالة بشكل كبير اعتماداً على تنفيذ نظامك. على سبيل المثال، لن تعمل عادةً عبر حدود أنظمة الملفات، رغم أن أمر نظام التشغيل mv يعوض عن ذلك أحياناً. تشمل القيود الأخرى ما إذا كانت تعمل على الأدلة، أو الملفات المفتوحة، أو الملفات الموجودة مسبقاً. تحقق من perlport وإما صفحة دليل rename(2) أو توثيق النظام المكافئ لمزيد من التفاصيل.

للحصول على دالة "move" مستقلة عن المنصة، انظر إلى وحدة File::Copy.

مشاكل النقلية: "rename" في perlport.

require VERSION
require EXPR
تتطلب إصداراً من Perl محدد بواسطة VERSION، أو تتطلب بعض المعاني المحددة بواسطة EXPR أو بواسطة $_ إذا لم يتم توفير EXPR.

قد تكون VERSION إما قيمة حرفية مثل v5.24.1، والتي ستتم مقارنتها بـ $^V (أو $PERL_VERSION بالإنجليزية)، أو وسيطاً رقمياً من الشكل 5.024001، والذي سيتم مقارنته بـ $]. يُثار استثناء إذا كانت VERSION أكبر من إصدار مفسر Perl الحالي. قارن مع "use"، التي يمكنها إجراء فحص مماثل في وقت التجميع.

ينبغي عموماً تجنب تحديد VERSION كفعل رقمي من الشكل 5.024001 لكونه بناءً قديمًا وأقل قابلية للقراءة مقارنة بـ v5.24.1. قبل perl 5.8.0 (الذي صُدر في 2002)، كان الشكل الرقمي الأكثر تفصيلاً هو بناء الجملة المدعوم الوحيد، ولهذا السبب قد تراه في الشفرات القديمة.

    require v5.24.1;    # فحص الإصدار في وقت التشغيل
    require 5.24.1;     # مثله
    require 5.024_001;  # مثله؛ بناء قديم متوافق
                          مع perl 5.6
    

خلاف ذلك، تتطلب "require" تضمين ملف مكتبة إذا لم يكن قد ضُمّن بالفعل. يُضمّن الملف عبر آلية do-FILE، والتي هي في الأساس مجرد نوع من "eval" مع التنبيه بأن المتغيرات المعجمية في السكربت المستدعي ستكون غير مرئية للكود المضمن. لو نُفذت بلغة Perl الصرفة، لكان لها دلالات مشابهة لما يلي:

    use Carp 'croak';
    use version;
    sub require {
        my ($filename) = @_;
        if ( my $version = eval { version->parse($filename) } ) {
            if ( $version > $^V ) {
               my $vn = $version->normal;
               croak "Perl $vn required--this is only $^V, stopped";
            }
            return 1;
        }
        if (exists $INC{$filename}) {
            return 1 if $INC{$filename};
            croak "Compilation failed in require";
        }
        local $INC;
        # هذا النوع من الحلقات يسمح للخطاف بإعادة كتابة $INC إذا رغب
        for($INC = 0; $INC < @INC; $INC++) {
            my $prefix = $INC[$INC];
            if (!defined $prefix) {
                next;
            }
            if (ref $prefix) {
                #... افعل أشياء أخرى - انظر النص أدناه ....
            }
            # (انظر النص أدناه حول إمكانية إلحاق لاحقة .pmc
            # بـ $filename)
            my $realfilename = "$prefix/$filename";
            next if ! -e $realfilename || -d _ || -b _;
            $INC{$filename} = $realfilename;
            my $result = do($realfilename);
                         # ولكن يعمل في فضاء تسمية المستدعي
            if (!defined $result) {
                $INC{$filename} = undef;
                croak $@ ? "$@Compilation failed in require"
                         : "Can't locate $filename: $!\n";
            }
            if (!$result) {
                delete $INC{$filename};
                croak "$filename did not return true value";
            }
            $! = 0;
            return $result;
        }
        croak "Can't locate $filename in \@INC ...";
    }
    

لاحظ أن الملف لن يتم تضمينه مرتين تحت نفس الاسم المحدد.

تاريخيًا يجب أن يعيد الملف قيمة صحيحة كآخر بيان للإشارة إلى التنفيذ الناجح لأي كود تهيئة، لذا جرى العرف على إنهاء مثل هذا الملف بـ "1;" ما لم تكن متأكدًا من أنه سيعيد قيمة صحيحة بخلاف ذلك. ولكن من الأفضل فقط وضع "1;"، تحسبًا لإضافة المزيد من البيانات. بدءًا من 5.37.6 يمكن تجنب هذا المتطلب بتمكين ميزة 'module_true'، والتي تُمكن مبدئيًا في حزم الإصدارات الحديثة. وبالتالي فإن الكود الذي يحتوي على "use v5.37;" لم يعد بحاجة للقلق بشأن هذه المسألة. انظر feature لمزيد من التفاصيل. لاحظ أن هذا يؤثر على وحدة التصريف التي تُستخدم فيها الميزة، واستخدامها قبل طلب وحدة (require) لن يغير سلوك الوحدات الحالية التي لا تستخدمها هي نفسها أيضًا.

إذا كان EXPR كلمة مجردة (bareword)، فإن "require" تفترض لاحقة .pm وتستبدل "::" بـ "/" في اسم الملف من أجلك، لتسهيل تحميل الوحدات القياسية. هذا الشكل من تحميل الوحدات لا يخاطر بتغيير فضاء التسمية الخاص بك، ومع ذلك فإنه سيحيي آلياً (autovivify) الـ stash للوحدة المطلوبة.

بمعنى آخر، إذا جربت هذا:

        require Foo::Bar;     # كلمة مجردة رائعة
    

ستبحث دالة require فعلياً عن ملف Foo/Bar.pm في الأدلة المحددة في مصفوفة @INC، وستحيي آلياً stash الـ "Foo::Bar::" في وقت التجميع.

ولكن إذا جربت هذا:

        my $class = 'Foo::Bar';
        require $class;       # ليس كلمة مجردة $class
    #أو
        require "Foo::Bar";   # ليس كلمة مجردة بسبب الـ ""
    

ستبحث دالة require عن ملف Foo::Bar في مصفوفة @INC وستشتكي من عدم العثور على Foo::Bar هناك. في هذه الحالة يمكنك القيام بـ:

        eval "require $class";
    

أو يمكنك القيام بـ

        require "Foo/Bar.pm";
    

لا يوجد أي من هذين الشكلين سيحيي آلياً أي stashes في وقت التجميع، ولهما فقط تأثيرات في وقت التشغيل.

الآن بعد أن فهمت كيف تبحث "require" عن الملفات باستخدام وسيط كلمة مجردة، هناك وظيفة إضافية صغيرة تحدث خلف الكواليس. قبل أن تبحث "require" عن ملحق .pm، ستبحث أولاً عن اسم ملف مماثل بملحق .pmc. إذا وُجد هذا الملف، فسيتم تحميله بدلاً من أي ملف ينتهي بملحق .pm. ينطبق هذا على كل من الشكل الصريح "require "Foo/Bar.pm";" وشكل "require Foo::Bar;".

يمكنك أيضاً إدراج خطافات (hooks) في مرفق الاستيراد بوضع مراجع أكواد Perl (coderefs) أو كائنات مباشرة في مصفوفة @INC. هناك نوعان من الخطافات، مرشحات INC، وخطافات INCDIR، وهناك ثلاثة أشكال لتمثيل الخطاف: مراجع البرامج الفرعية، ومراجع المصفوفات، والكائنات المباركة.

مراجع البرامج الفرعية هي الحالة الأبسط. عندما يمر نظام التضمين عبر @INC ويصادف برنامجاً فرعياً، فما لم يكن هذا البرنامج الفرعي مباركاً ويدعم خطاف INCDIR، فسيتم افتراض أنه خطاف INC وسيتم استدعاؤه بوسطين، الأول مرجع لنفسه، والثاني اسم الملف المراد تضمينه (مثلاً Foo/Bar.pm). يجب أن يعيد البرنامج الفرعي إما لا شيء أو قائمة تصل إلى أربع قيم بالترتيب التالي:

1.
مرجع لمتغير سلمي، يحتوي على أي شفرة مصدر أولية لإلحاقها في بداية الملف أو مخرجات المولد.
2.
ممسك ملف، يتم قراءة الملف منه.
3.
مرجع لبرنامج فرعي. إذا لم يكن هناك ممسك ملف (العنصر السابق)، فمن المتوقع أن يولد هذا البرنامج الفرعي سطراً واحداً من شفرة المصدر لكل استدعاء، بكاتبة السطر في $_ وإرجاع 1، ثم في نهاية الملف إرجاع 0. إذا وُجد ممسك ملف، فسيتم استدعاء البرنامج الفرعي ليعمل كمرشح مصدر بسيط، مع السطر كما قُرئ في $_. مرة أخرى، أعد 1 لكل سطر صالح، و 0 بعد إرجاع جميع الأسطر. لأسباب تاريخية، سيتلقى البرنامج الفرعي وسيطاً بلا معنى (في الواقع دائماً القيمة الرقمية صفر) كـ $_[0].
4.
حالة اختيارية للبرنامج الفرعي. يتم تمرير الحالة كـ $_[1].

لا يمكن استخدام "AUTOLOAD" لحل تابع "INCDIR"، يتم فحص "INC" أولاً، وسيقوم "AUTOLOAD" بحل ذلك.

إذا أُعيدت قائمة فارغة، أو "undef"، أو لا شيء يطابق القيم الثلاث الأولى أعلاه، فإن "require" تنظر في العناصر المتبقية من @INC. لاحظ أن ممسك الملف هذا يجب أن يكون ممسك ملف حقيقياً (تحديداً typeglob أو مرجع لـ typeglob، سواء كان مباركاً أم لا)؛ سيتم تجاهل ممسكات الملفات المربوطة (tied filehandles) وسيتوقف المعالجة هناك.

إذا كان الخطاف كائناً، فيجب أن يوفر تابع "INC" أو "INCDIR" سيتم استدعاؤه كما هو موضح أعلاه، ويكون الوسيط الأول هو الكائن نفسه. إذا لم يوفر أي منهما، ولم يكن الكائن CODE ref، فسيتم إثارة استثناء، وإلا فسيتم تنفيذه ببساطة كما يُنفذ CODE ref غير المبارك. لاحظ أنه يجب عليك تحديد اسم التابع بالكامل عند التصريح عن برنامج فرعي "INC" (على عكس برنامج "INCDIR" الفرعي)، لأن الرمز غير المؤهل "INC" يُفرض دائماً في الحزمة "main". إليك تخطيط شفرة نمطي لخطاف "INC":

    # في Foo.pm
    package Foo;
    sub new { ... }
    sub Foo::INC {
        my ($self, $filename) = @_;
        ...
    }
    # في البرنامج الرئيس
    push @INC, Foo->new(...);

إذا كان الخطاف (hook) مرجع مصفوفة، فيجب أن يكون عنصره الأول مرجع روتين فرعي أو كائناً كما هو موضح أعلاه. عندما يكون العنصر الأول كائناً يدعم تابع "INC" أو "INCDIR"، فسيُستدعى التابع مع الكائن كمعامل أول، واسم الملف المطلوب كمعامل ثانٍ، ومرجع مصفوفة الخطاف كمعامل ثالث. عندما يكون العنصر الأول روتيناً فرعياً، فسيُستدعى مع المصفوفة كمعامل أول، واسم الملف كمعامل ثانٍ، ولن يُمرر معامل ثالث. في كلا الشكلين، يمكنك تعديل محتويات المصفوفة لتوفير حالة بين الاستدعاءات، أو أي شيء تريده.

بمعنى آخر، يمكنك كتابة:

    push @INC, \&my_sub;
    sub my_sub {
        my ($coderef, $filename) = @_;  # $coderef هو \&my_sub
        ...
    }

أو:

    push @INC, [ \&my_sub, $x, $y, ... ];
    sub my_sub {
        my ($arrayref, $filename) = @_;
        # استرجع $x, $y, ...
        my (undef, @parameters) = @$arrayref;
        ...
    }

أو:

    push @INC, [ HookObj->new(), $x, $y, ... ];
    sub HookObj::INC {
        my ($self, $filename, $arrayref)= @_;
        my (undef, @parameters) = @$arrayref;
        ...
    }

يُسمح لهذه الخطافات (hooks) أيضًا بضبط مدخلة %INC المقابلة للملفات التي حمّلتها. راجع "%INC" في perlvar. إذا لم يقم خطاف "INC" بذلك، فسيضبط perl مدخلة %INC لتكون مرجع الخطاف نفسه.

يمكن استخدام الخطاف أيضًا لإعادة كتابة مصفوفة @INC. ومع أن هذا قد يبدو غريبًا، إلا أن هناك حالات يكون فيها القيام بذلك مفيدًا جدًا. عادةً ما تعيد مثل هذه الخطافات القيمة undef ولا تخلط بين التصفية وتعديلات @INC. وبينما كان تعديل @INC بواسطة خطاف في الإصدارات الأقدم من perl محفوفًا بالمشكلات وقد يؤدي حتى إلى أخطاء في تقسيم الذاكرة (segfaults) أو إخفاقات في التأكيد (assert failures)، فقد صُمم المنطق ليكون أكثر متانة بدءًا من الإصدار 5.37.7، وأصبح للخطاف الآن سيطرة على تكرار الحلقة إذا رغب في ذلك.

توجد الآن ميزة للتحكم في المكرر (iterator) الخاص بعبور مصفوفة @INC الذي يُجرى أثناء require. سيُهيأ المتغير $INC بفهرس الخطاف الذي يجري تنفيذه حاليًا. وبمجرد أن يعيد الخطاف قيمته، فإن الخانة التالية في @INC التي سيُتحقق منها ستكون القيمة التالية للعدد الصحيح في $INC (أو -1 إذا كانت القيمة undef). على سبيل المثال الكود التالي

    push @INC, sub {
        splice @INC, $INC, 1; # إزالة هذا الخطاف من @INC
        unshift @INC, sub { warn "A" };
        undef $INC; # إعادة ضبط مكرر $INC حتى
                    # ننفذ الدالة الفرعية المثبتة حديثًا
                    # فورًا.
    };

سيثبت دالة فرعية في @INC بحيث عند تنفيذها كخطاف (على سبيل المثال عند طلب require لملف غير موجود)، سيقوم الخطاف بفصل نفسه من @INC، وإضافة دالة فرعية جديدة إلى المقدمة تصدر تحذيرًا كلما قام شخص ما بعملية require تتطلب بحثًا في @INC، ثم ينفذ ذلك الخطاف فورًا.

قبل الإصدار 5.37.7، لم تكن هناك طريقة لجعل perl يستخدم الخطاف المثبت حديثًا فورًا، أو لفحص أي عناصر مغيرة في @INC إلى يسار المكرر، ولذلك لم يكن التحذير ليتولد إلا عند الاستدعاء الثاني لـ require. في إصدارات perl الأحدث، سيؤدي وجود العبارة الأخيرة التي تجعل $INC غير معرف (undef) إلى جعل perl يعيد بدء عبور مصفوفة @INC من البداية وينفذ الدالة الفرعية المثبتة حديثًا فورًا.

أي قيمة كانت تحملها $INC، إن وجدت، ستُستعاد في نهاية require. أي تغييرات تُجرى على $INC خلال فترة حياة الخطاف (hook) ستُتراجع بعد خروج الخطاف، وقيمتها لها معنى فقط فور تنفيذ الخطاف، لذا فإن ضبط $INC على قيمة ما قبل تنفيذ "require" لن يكون له أي تأثير على كيفية تنفيذ require على الإطلاق.

بدءاً من 5.37.7، ستُتجاهل قيم undef في @INC بصمت.

من الصعب تغليف الدالة require() بشكل سليم. العديد من الوحدات البرمجية تراجع المكدس (stack) للعثور على معلومات حول المستدعِي (caller)، وحقن إطار مكدس جديد عبر تغليف require() غالباً ما يكسر الأشياء. ومع ذلك، قد يكون من المفيد جداً امتلاك القدرة على أداء إجراءات قبل وبعد "require"، على سبيل المثال لأدوات التتبع مثل "Devel::TraceUse" أو لقياس وقت التحميل واستهلاك الذاكرة لرسم require البياني. بسبب الصعوبات في إنشاء مغلف آمن لـ require()، قدمنا في 5.37.10 آلية جديدة.

بدءاً من 5.37.10، وقبل أي إجراءات أخرى تقوم بها، ستتحقق "require" مما إذا كان "${^HOOK}{require__before}" يحتوي على مرجع برمجي (coderef)، وإذا كان الأمر كذلك، فسيُستدعى مع صيغة اسم الملف للعنصر الذي يجري تحميله. قد يعدل الخطاف $_[0] لتحميل اسم ملف مختلف، أو قد يرمي استثناءً قاتلاً للتسبب في فشل require، والذي سيُعامل كما لو أن الكود المطلوب نفسه قد رمى استثناءً.

قد يعيد الخطاف "${^HOOK}{require__before}" مرجع كود، وفي هذه الحالة سيُنفذ مرجع الكود (في eval مع اسم الملف كمعامل) بعد اكتمال require. وسيُنفذ بغض النظر عن كيفية اكتمال التصريف، وحتى لو ألقى require استثناءً قاتلاً. يمكن للدالة مراجعة %INC لتحديد ما إذا كان require قد فشل أم لا. على سبيل المثال، سيطبع الكود التالي بعض التشخيصات قبل وبعد كل جملة "require". يتضمن المثال أيضاً منطقاً لسلسلة الإشارة، بحيث يمكن لعدة إشارات أن تتعاون. يجب على معالجات "${^HOOK}{require__before}" جيدة السلوك دائماً أخذ ذلك في الاعتبار.

    {
        use Scalar::Util qw(reftype);
        my $old_hook = ${^HOOK}{require__before};
        local ${^HOOK}{require__before} = sub {
            my ($name) = @_;
            my $old_hook_ret;
            $old_hook_ret = $old_hook->($name) if $old_hook;
            warn "Requiring: $name\n";
            return sub {
                $old_hook_ret->() if ref($old_hook_ret)
                                  && reftype($old_hook_ret) eq "CODE";
                warn sprintf "Finished requiring %s: %s\n",
                        $name, $INC{$name} ? "loaded" :"failed";
            };
        };
        require Whatever;
    }

يُنفذ هذا الخطاف لكل جمل "require"، على عكس خطافات "INC" و "INCDIR" التي تُنفذ فقط لأسماء الملفات النسبية، ويُنفذ أولاً قبل أي سلوك خاص آخر داخل require. لاحظ أن الخطاف الأولي في "${^HOOK}{require__before}" *لا* يُنفذ داخل eval، ورمي استثناء سيوقف المعالجة الإضافية، لكن خطاف "ما بعد" (after hook) الذي قد يعيده يُنفذ داخل eval، وأي استثناءات يرميها سيُتجاهل بصمت. هذا لأنه يُنفذ داخل منطق تنظيف النطاق (scope cleanup) الذي يُفعّل بعد اكتمال require، والاستثناء في هذا الوقت لن يوقف تحميل الوحدة، وما إلى ذلك.

يوجد خطاف مماثل ينطلق بعد اكتمال require، وهو "${^HOOK}{require__after}"، والذي سيُستدعى بعد اكتمال كل جملة require، سواء عبر استثناء أو بنجاح. سيُستدعى مع اسم ملف جملة require التي نُفذت مؤخراً. يُنفذ في eval، ولن يؤثر بأي حال من الأحوال على التنفيذ.

لمرفق استيراد أكثر قوة مبني حول "require"، راجع "use" و perlmod.

reset EXPR
يُستخدم عموماً في كتلة "continue" في نهاية حلقة لمسح المتغيرات وإعادة ضبط عمليات بحث "m?pattern?" لتعمل مرة أخرى. يُفسر التعبير كقائمة من أحرف مفردة (يُسمح بالواصلات للنطاقات). جميع المتغيرات (القيم القياسية، المصفوفات، والمجموعات) في الحزمة الحالية التي تبدأ بأحد تلك الأحرف تُعاد إلى حالتها الأصلية. إذا حُذف التعبير، تُعاد عمليات البحث ذات المطابقة الواحدة ("m?pattern?") لتطابق مرة أخرى. يعيد الضبط فقط للمتغيرات أو عمليات البحث في الحزمة الحالية. يعيد دائماً 1. أمثلة:

    reset 'X';      # إعادة ضبط جميع متغيرات X
    reset 'a-z';    # إعادة ضبط المتغيرات الصغيرة
    reset;          # فقط إعادة ضبط عمليات بحث m?one-time?
    

لا يُوصى بإعادة تعيين "A-Z" لأنك ستمسح مصفوفات @ARGV و @INC وهش %ENV الخاص بك.

يعيد تعيين متغيرات الحزمة فقط؛ لا تتأثر المتغيرات المعجمية، لكنها تنظف نفسها عند الخروج من النطاق على أي حال، لذا فمن المحتمل أنك سترغب في استخدامها بدلاً من ذلك. انظر "my".

return EXPR
يعود من دالة فرعية، أو "eval"، أو "do FILE"، أو كتلة "sort" أو كتلة eval لتعبير نمطي (ولكن ليس كتلة "grep" أو "map" أو "do BLOCK") بالقيمة المعطاة في EXPR. قد يكون تقييم EXPR في سياق قائمة أو سياق قياسي أو سياق باطل، اعتماداً على كيفية استخدام القيمة المعادة، وقد يختلف السياق من تنفيذ لآخر (راجع "wantarray"). إذا لم يُعطَ EXPR، فإنه يعيد قائمة فارغة في سياق القائمة، والقيمة غير المعرفة (undefined) في السياق القياسي، و(بالطبع) لا شيء على الإطلاق في السياق الباطل.

(في غياب "return" صريح، تعيد الدالة الفرعية أو "eval" أو "do FILE" آلياً قيمة آخر تعبير جرى تقييمه.)

على عكس معظم المعاملات المسماة، يُعفى هذا أيضاً من قاعدة "يبدو كدالة"، لذا فإن "return ("foo")."bar"" سيجعل "bar" جزءاً من المعامل الممرر لـ "return".

في سياق القائمة، يعيد قيمة قائمة تتكون من عناصر LIST بترتيب عكسي. في السياق القياسي، يدمج عناصر LIST ويعيد قيمة نصية بجميع الأحرف بترتيب عكسي.

    print join(", ", reverse "world", "Hello"); # Hello, world
    print scalar reverse "dlrow ,", "olleH";    # Hello, world
    

إذا استُخدم بدون معاملات في سياق قياسي، فإن "reverse" يعكس قيمة $_.

    $_ = "dlrow ,olleH";
    print reverse;                         # لا مخرجات، سياق قائمة
    print scalar reverse;                  # Hello, world
    

لاحظ أن عكس مصفوفة إلى نفسها (كما في "@a = reverse @a") سيحافظ على العناصر غير الموجودة كلما كان ذلك ممكناً؛ أي للمصفوفات غير السحرية أو للمصفوفات المربوطة (tied) التي تمتلك طرق "EXISTS" و "DELETE".

هذا المعامل مفيد أيضاً لعكس مجموعة (hash)، على الرغم من وجود بعض المحاذير. إذا كانت القيمة مكررة في المجموعة الأصلية، فيمكن تمثيل واحدة منها فقط كمفتاح في المجموعة المعكوسة. أيضاً، يتعين على هذا فك مجموعة واحدة وبناء واحدة جديدة تماماً، مما قد يستغرق بعض الوقت في المجموعات الكبيرة، مثل تلك الناتجة من ملف DBM.

    my %by_name = reverse %by_address;  # عكس المجموعة
    
يضبط الموضع الحالي إلى بداية الدليل لروتين "readdir" على DIRHANDLE.

مسائل القابلية للنقل: "rewinddir" في perlport.

يعمل تماماً مثل "index" باستثناء أنه يعيد موضع آخر ظهور لـ SUBSTR في STR. إذا جرى تحديد POSITION، فإنه يعيد آخر ظهور يبدأ عند ذلك الموضع أو قبله.
rmdir FILENAME
يحذف الدليل المحدد بواسطة FILENAME إذا كان هذا الدليل فارغاً. إذا نجح، يعيد true؛ وإلا يعيد false ويضبط $!‏ (errno). إذا حُذف FILENAME، يستخدم $_.

لإزالة شجرة دليل بشكل متكرر ("rm -rf" على يونكس) راجع دالة "rmtree" في وحدة File::Path.

معامل الاستبدال. راجع "Regexp Quote-Like Operators" في perlop.
say FILEHANDLE LIST
say FILEHANDLE
say LIST
تماماً مثل "print"، ولكنه يلحق سطراً جديداً ضمنياً في نهاية LIST بدلاً من أي قيمة قد تحملها "$\". لاستخدام FILEHANDLE بدون LIST لطباعة محتويات $_ إليه، يجب استخدام مقبض ملف صريح مثل "FH"، وليس مقبضاً غير مباشر مثل $fh.

دالة "say" متاحة فقط إذا تم تمكين ميزة "say" أو إذا كانت مسبوقة بـ "CORE::". يتم تمكين ميزة "say" تلقائيًا عند التصريح عن استخدام "use v5.10" (أو إصدار أحدث) في النطاق الحالي.

يجبر EXPR على أن يُفسر في سياق قياسي ويعيد قيمة EXPR.

    my @counts = ( scalar @a, scalar @b, scalar @c );
    

لا يوجد معامل مكافئ لإجبار تعبير على أن يُفسر في سياق قائمة لأنه في الممارسة العملية، لا تبرز الحاجة إلى ذلك أبداً. ومع ذلك، إذا أردت فعلاً القيام بذلك، يمكنك استخدام البناء "@{[ (some expression) ]}"، ولكن عادةً ما يكفي التعبير البسيط "(some expression)".

لأن "scalar" معامل أحادي، فإذا استخدمت بالخطأ قائمة بين قوسين لـ EXPR، فسيتصرف هذا كتعبير فاصلة قياسي، حيث يُقيم جميع العناصر باستثناء الأخير في سياق باطل ويعيد العنصر الأخير مُقيماً في سياق قياسي. نادراً ما يكون هذا هو المطلوب.

الجملة الواحدة التالية:

    print uc(scalar(foo(), $bar)), $baz;
    

هي المكافئ المعنوي لهاتين الجملتين:

    foo();
    print(uc($bar), $baz);
    

راجع perlop لمزيد من التفاصيل حول المعاملات الأحادية ومعامل الفاصلة، وراجع perldata للحصول على تفاصيل حول تقييم المجموعة في سياق قياسي.

يضبط موضع FILEHANDLE، تماماً مثل استدعاء fseek(3) في لغة C "stdio". قد يكون FILEHANDLE تعبيراً تعطي قيمته اسم مقبض الملف. قيم WHENCE هي 0 لضبط الموضع الجديد بالبايت إلى POSITION؛ و 1 لضبطه على الموضع الحالي زائد POSITION؛ و 2 لضبطه على نهاية الملف (EOF) زائد POSITION، وعادة ما تكون القيمة سالبة. بالنسبة لـ WHENCE، يمكنك استخدام الثوابت "SEEK_SET" و "SEEK_CUR" و "SEEK_END" (بداية الملف، الموضع الحالي، نهاية الملف) من وحدة Fcntl النمطية. يعيد 1 عند النجاح، وقيمة خاطئة بخلاف ذلك.

لاحظ التأكيد على البايتات: حتى لو ضُبط مقبض الملف ليعمل على الأحرف (على سبيل المثال باستخدام طبقة الإدخال/الإخراج :encoding(UTF-8))، فإن عائلة الدوال "seek" و "tell" و "sysseek" تستخدم إزاحات البايت، وليس إزاحات الأحرف، لأن البحث إلى إزاحة أحرف سيكون بطيئاً جداً في ملف UTF-8.

إذا كنت تريد وضع الملف لـ "sysread" أو "syswrite"، فلا تستخدم "seek"، لأن التخزين المؤقت يجعل تأثيره على موضع القراءة والكتابة في الملف غير متوقع وغير منقول. استخدم "sysseek" بدلاً من ذلك.

نظراً لقواعد وصرامة ANSI C، يتعين عليك في بعض الأنظمة إجراء عملية seek كلما انتقلت بين القراءة والكتابة. ومن بين أمور أخرى، قد يكون لهذا تأثير استدعاء clearerr(3) الخاص بـ stdio. قيمة WHENCE تبلغ 1 ("SEEK_CUR") مفيدة لعدم تحريك موضع الملف:

    seek($fh, 0, 1);
    

هذا مفيد أيضاً للتطبيقات التي تحاكي "tail -f". بمجرد وصولك إلى نهاية الملف (EOF) في قراءتك ثم النوم لفترة من الوقت، سيتعين عليك (على الأرجح) إدراج "seek" وهمي لإعادة ضبط الأمور. لا تغير "seek" الموضع، ولكنها تمسح حالة نهاية الملف على المقبض، بحيث تجعل "readline FILE" التالية Perl يحاول القراءة مرة أخرى. (نأمل ذلك.)

إذا لم يفلح ذلك (بعض تنفيذات الإدخال/الإخراج سيئة الطبع بشكل خاص)، فقد تحتاج إلى شيء كهذا:

    for (;;) {
        for ($curpos = tell($fh); $_ = readline($fh);
             $curpos = tell($fh)) {
            # البحث عن بعض الأشياء ووضعها في ملفات
        }
        sleep($for_a_while);
        seek($fh, $curpos, 0);
    }
    
يضبط الموضع الحالي لروتين "readdir" على DIRHANDLE. يجب أن تكون POS قيمة معادة بواسطة "telldir". تمتلك "seekdir" أيضاً نفس المحاذير المتعلقة باحتمالية ضغط الدليل كما في روتين مكتبة النظام المقابل.
select FILEHANDLE
يعيد مقبض الملف المختار حالياً. إذا جرى توفير FILEHANDLE، فإنه يضبط مقبض الملف المبدئي الجديد للمخرجات. هذا له تأثيران: أولاً، جمل "write" أو "print" أو "say" بدون مقبض ملف ستتخذ هذا الـ FILEHANDLE كمبدئي. ثانياً، ستشير المتغيرات المتعلقة بالمخرجات إلى قناة المخرجات هذه.

على سبيل المثال، لضبط تنسيق رأس الصفحة (top-of-form) لأكثر من قناة مخرجات واحدة، قد تفعل ما يلي:

    select(REPORT1);
    $^ = 'report1_top';
    select(REPORT2);
    $^ = 'report2_top';
    

قد يكون FILEHANDLE تعبيراً تعطي قيمته اسم مقبض الملف الفعلي. هكذا:

    my $oldfh = select(STDERR); $| = 1; select($oldfh);
    

قد يفضل بعض المبرمجين التفكير في مقابض الملفات ككائنات ذات دوال (methods)، مفضلين كتابة المثال الأخير هكذا:

    STDERR->autoflush(1);
    

(قبل إصدار بيرل 5.14، كان عليك استخدام "use IO::Handle;" صراحة أولاً.)

بينما يمكنك استخدام "select" مؤقتاً لـ "التقاط" مخرجات "print" بهذا الشكل:

    {
        my $old_handle = select $new_handle;
        # يذهب هذا إلى $new_handle:
        print "ok 1\n";
        ...
        select $old_handle;
    }
    

قد تجد أنه من الأسهل جعل (typeglob) محلياً بدلاً من ذلك:

    {
        local *STDOUT = $new_handle;
        print "ok 1\n";
        ...
    }
    

الاثنان ليسوا متكافئين تماماً، لكن الأخير قد يكون أوضح وسيعيد STDOUT إذا توقف الكود المغلف عن العمل. الفرق هو أنه في الحالة الأولى، لا يزال من الممكن الوصول إلى STDOUT الأصلي باستخدامه صراحة في جملة "print" (مثل "print STDOUT ...")، بينما في الحالة الثانية تغير معنى مقبض STDOUT نفسه مؤقتاً.

مسائل القابلية للنقل: "select" في perlport.

select RBITS,WBITS,EBITS,TIMEOUT
يستدعي هذا نداء النظام select(2) مع أقنعة البت المحددة، والتي يمكن بناؤها باستخدام "fileno" و "vec"، على هذا النحو:

    my $rin = my $win = my $ein = '';
    vec($rin, fileno(STDIN),  1) = 1;
    vec($win, fileno(STDOUT), 1) = 1;
    $ein = $rin | $win;
    

إذا أردت استخدام select على العديد من مقابض الملفات، قد ترغب في كتابة دالة فرعية كهذه:

    sub fhbits {
        my @fhlist = @_;
        my $bits = "";
        for my $fh (@fhlist) {
            vec($bits, fileno($fh), 1) = 1;
        }
        return $bits;
    }
    my $rin = fhbits(\*STDIN, $tty, $mysock);
    

الأسلوب المعتاد هو:

 my ($nfound, $timeleft) =
   select(my $rout = $rin, my $wout = $win, my $eout = $ein,
                                                          $timeout);
    

أو للمنع (block) حتى يصبح شيء ما جاهزاً، فقط افعل هذا

 my $nfound =
   select(my $rout = $rin, my $wout = $win, my $eout = $ein, undef);
    

معظم الأنظمة لا تهتم بإرجاع أي شيء مفيد في $timeleft، لذا فإن استدعاء "select" في سياق قياسي يعيد فقط $nfound.

أي من أقنعة البت يمكن أن يكون أيضاً "undef". المهلة (timeout)، إذا جرى تحديدها، تكون بالثواني، ويمكن أن تكون كسرية. ملاحظة: ليست كل التطبيقات قادرة على إرجاع $timeleft. إذا لم تكن كذلك، فإنها تعيد دائماً $timeleft مساوية لـ $timeout الموفرة.

يمكنك إحداث نوم لمدة 250 مللي ثانية بهذه الطريقة:

    select(undef, undef, undef, 0.25);
    

لاحظ أن إعادة تشغيل "select" بعد الإشارات (مثل SIGALRM) يعتمد على التطبيق. راجع أيضاً perlport لملاحظات حول قابلية نقل "select".

عند حدوث خطأ، يتصرف "select" تماماً مثل select(2): يعيد -1 ويضبط $!.

في بعض أنظمة يونكس، قد يبلغ select(2) عن واصف ملف سوكيت بأنه "جاهز للقراءة" حتى عندما لا تتوفر بيانات، وبالتالي فإن أي عملية "read" لاحقة ستُمنع (block). يمكن تجنب ذلك إذا كنت تستخدم دائماً "O_NONBLOCK" على السوكيت. راجع select(2) و fcntl(2) لمزيد من التفاصيل.

توفر وحدة "IO::Select" القياسية واجهة أكثر سهولة للمستخدم لـ "select"، غالباً لأنها تقوم بكل أعمال أقنعة البت نيابة عنك.

تحذير: لا ينبغي محاولة خلط الإدخال/الإخراج المخزن مؤقتاً (مثل "read" أو "readline") مع "select"، إلا كما هو مسموح به في POSIX، وحتى في ذلك الوقت فقط على أنظمة POSIX. يجب استخدام "sysread" بدلاً من ذلك.

مسائل القابلية للنقل: "select" في perlport.

يستدعي دالة System V IPC المسماة semctl(2). من المحتمل أن تضطر لقول

    use IPC::SysV;
    

أولاً للحصول على تعريفات الثوابت الصحيحة. إذا كان CMD هو IPC_STAT أو GETALL، فيجب أن يكون ARG متغيراً سيحمل بنية semid_ds المعادة أو مصفوفة قيم السيمافور. يعيد نتائج مثل "ioctl": القيمة غير المعرفة للخطأ، أو ""0 but true"" للصفر، أو قيمة الإعادة الفعلية بخلاف ذلك. يجب أن يتكون ARG من متجه من الأعداد الصحيحة القصيرة الأصلية (native short integers)، والتي يمكن إنشاؤها باستخدام "pack("s!",(0)x$nsem)". راجع أيضاً "SysV IPC" في perlipc والتوثيق لـ "IPC::SysV" و "IPC::Semaphore".

مسائل القابلية للنقل: "semctl" في perlport.

يستدعي وظيفة System V IPC‏ semget(2). يعيد معرف السيمافور، أو القيمة غير المعرفة عند الخطأ. راجع أيضاً "SysV IPC" في perlipc والتوثيق لـ "IPC::SysV" و "IPC::Semaphore".

مسائل القابلية للنقل: "semget" في perlport.

يستدعي وظيفة System V IPC‏ semop(2) لعمليات السيمافور مثل الإرسال والانتظار. يجب أن يكون OPSTRING مصفوفة محزمة من بنيات semop. يمكن إنشاء كل بنية semop باستخدام "pack("s!3", $semnum, $semop, $semflag)". طول OPSTRING يشير إلى عدد عمليات السيمافور. يعيد true إذا نجح، و false عند الخطأ. كمثال، الكود التالي ينتظر السيمافور $semnum الخاص بمعرف السيمافور $semid:

    my $semop = pack("s!3", $semnum, -1, 0);
    die "Semaphore trouble: $!\n" unless semop($semid, $semop);
    

لإرسال إشارة إلى السيمافور، استبدل -1 بـ 1. راجع أيضاً "SysV IPC" في perlipc والتوثيق لـ "IPC::SysV" و "IPC::Semaphore".

مسائل القابلية للنقل: "semop" في perlport.

يرسل رسالة عبر سوكيت. يحاول إرسال القيمة القياسية MSG إلى مقبض الملف SOCKET. يأخذ نفس الأعلام (flags) كاستدعاء النظام الذي يحمل نفس الاسم. في السوكيتات غير المتصلة، يجب تحديد وجهة لـ الإرسال إليها، وفي هذه الحالة يقوم باستدعاء نظام sendto(2). يعيد عدد الأحرف المرسلة، أو القيمة غير المعرفة عند الخطأ. استدعاء النظام sendmsg(2) غير مطبق حالياً. راجع "UDP: Message Passing" في perlipc للأمثلة.

لاحظ أنه إذا وُسم السوكيت بـ ":utf8"، فإن "send" سيرمي استثناءً. طبقة :encoding(...) تقدم طبقة ":utf8" ضمنياً. راجع "binmode".

يضبط مجموعة العمليات الحالية لمعرف العملية (PID) المحدد، أو 0 للعملية الحالية. يُلقي استثناءً عند استخدامه على جهاز لا ينفذ POSIX setpgid(2) أو BSD setpgrp(2). إذا حُذفت المعاملات، فإنه يُعين مبدئيًا إلى "0,0". لاحظ أن إصدار BSD 4.2 من "setpgrp" لا يقبل أي معاملات، لذا فإن "setpgrp(0,0)" فقط هو القابل للنقل. انظر أيضاً POSIX::setsid().

مسائل القابلية للنقل: "setpgrp" في perlport.

يضبط الأولوية الحالية لعملية، أو مجموعة عمليات، أو مستخدم. (انظر setpriority(2).) يُلقي استثناءً عند استخدامه على جهاز لا ينفذ setpriority(2).

يمكن أن تكون "WHICH" أي واحدة من "PRIO_PROCESS"، أو "PRIO_PGRP"، أو "PRIO_USER" المستوردة من "RESOURCE CONSTANTS" في POSIX.

مسائل القابلية للنقل: "setpriority" في perlport.

يضبط خيار السوكيت المطلوب. يعيد "undef" عند الخطأ. استخدم ثوابت الأعداد الصحيحة التي توفرها وحدة "Socket" لـ LEVEL و OPNAME. يمكن أيضاً الحصول على قيم LEVEL من getprotobyname. قد يكون OPTVAL إما نصاً محزماً أو عدداً صحيحاً. العدد الصحيح لـ OPTVAL هو اختصار لـ pack("i", OPTVAL).

مثال على تعطيل خوارزمية Nagle على مقبس:

    use Socket qw(IPPROTO_TCP TCP_NODELAY);
    setsockopt($socket, IPPROTO_TCP, TCP_NODELAY, 1);
    

مسائل القابلية للنقل: "setsockopt" في perlport.

shift ARRAY
يزيل ويعيد العنصر الأول من المصفوفة. هذا يقصر المصفوفة بمقدار عنصر واحد وينقل كل شيء لأسفل.

    my @arr  = ('cat', 'dog');
    my $item = shift(@arr); # 'cat'
    # @arr الآن هي ('dog');
    

يعيد undef إذا كانت المصفوفة فارغة.

ملاحظة: قد يعيد "shift" أيضاً "undef" إذا كان العنصر الأول في المصفوفة هو "undef".

    my @arr  = (undef, 'two', 'three');
    my $item = shift(@arr); # undef
    

إذا حُذفت ARRAY، فإن "shift" يعمل على مصفوفة @ARGV في البرنامج الرئيس، ومصفوفة @_ في الدوال الفرعية. سيعمل "shift" على مصفوفة @ARGV في كتل "eval STRING" و "BEGIN {}" و "INIT {}" و "CHECK {}".

بدءاً من بيرل 5.14، سمحت ميزة تجريبية لـ "shift" بأن يأخذ تعبيراً قياسياً. جرى اعتبار هذه التجربة غير ناجحة، وأزيلت اعتباراً من بيرل 5.24.

انظر أيضًا "unshift"، و "push"، و "pop". تُجري "shift" و "unshift" الأمر ذاته على الطرف الأيسر للمصفوفة كما تفعل "pop" و "push" على الطرف الأيمن.

يستدعي دالة System V IPC المسماة shmctl. من المحتمل أن تضطر لقول

    use IPC::SysV;
    

أولاً للحصول على تعريفات الثوابت الصحيحة. إذا كانت CMD هي "IPC_STAT"، فيجب أن يكون ARG متغيرًا سيحمل بنية "shmid_ds" المعادة. القيمة المعادة تشبه ioctl: "undef" للخطأ؛ و "0 but true" للصفر؛ والقيمة المعادة الفعلية في الحالات الأخرى. انظر أيضًا "SysV IPC" في perlipc والتوثيق الخاص بـ "IPC::SysV".

مسائل قابلية النقل: "shmctl" في perlport.

يستدعي دالة System V IPC المسماة shmget. يعيد معرف (id) قطعة الذاكرة المشتركة، أو "undef" عند حدوث خطأ. انظر أيضًا "SysV IPC" في perlipc والتوثيق الخاص بـ "IPC::SysV".

مسائل قابلية النقل: "shmget" في perlport.

يقرأ أو يكتب في قطعة الذاكرة المشتركة System V ذات المعرف ID بدءًا من الموضع POS وبحجم SIZE عبر الوصل بها، والنسخ منها أو إليها، ثم الفصل عنها. عند القراءة، يجب أن يكون VAR متغيرًا يحفظ البيانات المقروءة. عند الكتابة، إذا كانت STRING طويلة جدًا، تُستخدم SIZE بايتات فقط؛ وإذا كانت STRING قصيرة جدًا، تُكتب أصفار (nulls) لملء بايتات SIZE. تعيد قيمة صواب (true) في حال النجاح، وخطأ (false) عند حدوث خطأ. تؤدي "shmread" إلى تلويث (taint) المتغير. انظر أيضًا "SysV IPC" في perlipc والتوثيق الخاص بـ "IPC::SysV" ووحدة "IPC::Shareable" من CPAN.

مسائل قابلية النقل: "shmread" في perlport و "shmwrite" في perlport.

يُغلق اتصال المقبس بالطريقة المحددة في HOW، والتي لها التفسير ذاته الموجود في نداء النظام (syscall) الذي يحمل الاسم نفسه.

    shutdown($socket, 0);    # توقفتُ/توقفنا عن قراءة البيانات
    shutdown($socket, 1);    # توقفتُ/توقفنا عن كتابة البيانات
    shutdown($socket, 2);    # توقفتُ/توقفنا عن استخدام هذا المقبس
    

هذا مفيد مع المقابس عندما تريد إخبار الطرف الآخر أنك انتهيت من الكتابة ولكن ليس من القراءة، أو العكس. إنه أيضاً شكل أكثر إصراراً من الإغلاق (close) لأنه يعطل أيضاً واصف الملف في أي نسخ متفرعة (forked) في عمليات أخرى.

يعيد 1 في حال النجاح؛ وعند الخطأ، يعيد "undef" إذا لم يكن المعامل الأول مقبض ملف صالحًا، أو يعيد 0 ويضبط $! لأي فشل آخر.

sin EXPR
يعيد جيب (sine) القيمة EXPR (معبرًا عنها بالراديان). إذا حُذفت EXPR، يعيد جيب $_.

لعملية جيب التمام العكسية، يمكنك استخدام دالة "Math::Trig::asin"، أو استخدام هذه العلاقة:

    sub asin { atan2($_[0], sqrt(1 - $_[0] * $_[0])) }
    
sleep EXPR
يجعل السكربت ينام لعدد (صحيح) EXPR من الثواني، أو للأبد إذا لم يُقدم أي معامل. يعيد العدد الصحيح للثواني التي نامها السكربت فعليًا.

يجب أن تكون EXPR عددًا صحيحًا موجبًا. إذا استُدعيت بعدد صحيح سالب، فإن "sleep" لا تنام بل تصدر تحذيرًا، وتضبط $! ("errno")، وتعيد صفرًا.

إذا استُدعيت بعدد غير صحيح، يتم تجاهل الجزء الكسري.

يُسمح بـ "sleep 0"، ولكن لا يزال استدعاء الدالة للمنصة التحتية يحدث، مع ما قد يترتب على ذلك من آثار جانبية. لذا فإن "sleep 0" ليست مطابقة تمامًا لعدم النوم على الإطلاق.

يمكن مقاطعتها إذا تلقت العملية إشارة مثل "SIGALRM".

    eval {
        local $SIG{ALRM} = sub { die "Alarm!\n" };
        sleep;
    };
    die $@ unless $@ eq "Alarm!\n";
    

ربما لا يمكنك خلط استدعاءات "alarm" و "sleep"، لأن "sleep" غالبًا ما تُنفذ باستخدام "alarm".

في بعض الأنظمة القديمة، قد تنام لأقل من ثانية كاملة مما طلبته، اعتمادًا على كيفية عد الثواني. معظم الأنظمة الحديثة تنام دائمًا كامل المدة. ومع ذلك، قد تبدو وكأنها تنام لفترة أطول، لأن عمليتك قد لا تُجدول فورًا في نظام متعدد المهام ومزدحم.

بالنسبة للتأخيرات ذات الدقة الأعلى من ثانية واحدة، توفر وحدة Time::HiRes (من CPAN، وبدءاً من Perl 5.8 كجزء من التوزيع القياسي) دالة "usleep". يمكنك أيضاً استخدام إصدار Perl ذي المعاملات الأربعة من "select" مع ترك المعاملات الثلاثة الأولى غير محددة، أو قد تتمكن من استخدام واجهة "syscall" للوصول إلى setitimer(2) إذا كان نظامك يدعم ذلك. انظر perlfaq8 لمزيد من التفاصيل.

انظر أيضاً دالة "pause" في وحدة POSIX النمطية.

يفتح مقبسًا من النوع المحدد ويوصله بمقبض الملف SOCKET. تُحدد قيم DOMAIN و TYPE و PROTOCOL بنفس الطريقة المتبعة في نداء النظام الذي يحمل الاسم نفسه. يجب عليك كتابة "use Socket" أولاً لاستيراد التعريفات المناسبة. انظر الأمثلة في "Sockets: Client/Server Communication" في perlipc.

في الأنظمة التي تدعم علم الإغلاق عند التنفيذ (close-on-exec) في الملفات، سيُضبط العلم لواصف الملف المفتوح حديثًا، كما هو محدد بواسطة قيمة $^F. راجع "$^F" في perlvar.

يُنشئ زوجًا غير مسمى من المقابس في النطاق المحدد، ومن النوع المحدد. تُحدد DOMAIN و TYPE و PROTOCOL بنفس طريقة نداء النظام الذي يحمل الاسم نفسه. إذا لم تكن منفذة، ترفع استثناءً. تعيد صواب (true) في حال النجاح.

في الأنظمة التي تدعم علامة الإغلاق عند التنفيذ (close-on-exec) على الملفات، سيتم ضبط العلامة لواصفات الملفات المفتوحة حديثًا، كما تُحددها قيمة $^F. انظر "$^F" في perlvar.

بعض الأنظمة تعرف "pipe" بدلالة "socketpair"، حيث يكون استدعاء "pipe($rdr, $wtr)" في الأساس:

    use Socket;
    socketpair(my $rdr, my $wtr, AF_UNIX, SOCK_STREAM, PF_UNSPEC);
    shutdown($rdr, 1);        # لا مزيد من الكتابة للقارئ
    shutdown($wtr, 0);        # لا مزيد من القراءة للكاتب
    

انظر perlipc لمثال على استخدام socketpair. ستقوم Perl 5.8 والإصدارات الأحدث بمحاكاة socketpair باستخدام مقابس IP للمضيف المحلي (localhost) إذا كان نظامك ينفذ المقابس ولكن ليس socketpair.

مسائل قابلية النقل: "socketpair" في perlport.

في سياق القائمة، تقوم هذه الدالة بفرز LIST وتعيد قيمة القائمة المفرزة. أما في السياق السلمي (scalar)، فإن سلوك "sort" غير محدد.

إذا حُذفت SUBNAME أو BLOCK، يتم الـ "sort" بترتيب مقارنة السلاسل القياسي. إذا حُددت SUBNAME، فإنها تعطي اسم روتين فرعي يعيد قيمة رقمية أقل من، أو تساوي، أو أكبر من 0، اعتمادًا على كيفية ترتيب عناصر القائمة. (العاملان "<=>" و "cmp" مفيدان للغاية في هذه الروتينات.) قد يكون SUBNAME اسم متغير سلمي (بدون فهرس)، وفي هذه الحالة توفر القيمة اسم (أو مرجعًا لـ) الروتين الفرعي الفعلي المستخدم. وبدلاً من SUBNAME، يمكنك توفير BLOCK كروتين فرعي للفرز مجهول ومضمن.

إذا كان النموذج الأولي للروتين الفرعي هو "($$)"، فإن العناصر المراد مقارنتها تُمرر بالمرجع في @_، كما هو الحال في الروتين الفرعي العادي. هذا أبطأ من الروتينات الفرعية التي لا تحتوي على نموذج أولي، حيث تُمرر العناصر المراد مقارنتها إلى الروتين الفرعي كمتغيرات عالمية للحزمة $a و $b (انظر المثال أدناه).

إذا كان الروتين الفرعي XSUB، تُدفع العناصر المراد مقارنتها إلى المكدس (stack)، بالطريقة التي تُمرر بها المعاملات عادةً إلى XSUBs. لا يتم ضبط $a و $b.

إذا كانت مقارنة عنصرين أو أكثر من LIST متساوية (أي تعيد عملية المقارنة 0 لهما)، فإنهما يحتفظان بالترتيب النسبي الذي كانا عليه في LIST. بمعنى آخر، الفرز مستقر (وهو كذلك منذ الإصدار v5.8.0).

تُمرر القيم المراد مقارنتها دائمًا بالمرجع ولا ينبغي تعديلها.

لا يمكنك أيضًا الخروج من كتلة الفرز أو الروتين الفرعي باستخدام أي من عوامل التحكم في الحلقات الموصوفة في perlsyn أو باستخدام "goto".

عندما يكون "use locale" (ولكن ليس "use locale ':not_characters'") مفعلًا، تقوم "sort LIST" بفرز LIST وفقًا لإعدادات المقارنة المحلية الحالية (collation locale). انظر perllocale.

"sort" تعيد أسماءً مستعارة (aliases) في القائمة الأصلية، تماماً كما يُنشئ متغير فهرس حلقة for أسماءً مستعارة لعناصر القائمة. أي أن تعديل عنصر من قائمة أعادتها "sort" (على سبيل المثال، في "foreach" أو "map" أو "grep") يعدل فعلياً العنصر في القائمة الأصلية. وعادةً ما يكون هذا شيئاً يجب تجنبه عند كتابة كود واضح.

أمثلة:

    # فرز معجمي
    my @articles = sort @files;
    # نفس الشيء، ولكن مع روتين فرز صريح
    my @articles = sort {$a cmp $b} @files;
    # الآن مع عدم الحساسية لحالة الأحرف
    my @articles = sort {fc($a) cmp fc($b)} @files;
    # نفس الشيء بترتيب عكسي
    my @articles = sort {$b cmp $a} @files;
    # فرز عددي تصاعدي
    my @articles = sort {$a <=> $b} @files;
    # فرز عددي تنازلي
    my @articles = sort {$b <=> $a} @files;
    # هذا يفرز هش %age حسب القيمة بدلاً من المفتاح
    # باستخدام دالة مدمجة (in-line)
    my @eldest = sort { $age{$b} <=> $age{$a} } keys %age;
    # فرز باستخدام اسم روتين فرعي صريح
    sub byage {
        $age{$a} <=> $age{$b};  # بافتراض أنه عددي
    }
    my @sortedclass = sort byage @class;
    sub backwards { $b cmp $a }
    my @harry  = qw(dog cat x Cain Abel);
    my @george = qw(gone chased yz Punished Axed);
    print sort @harry;
        # يطبع AbelCaincatdogx
    print sort backwards @harry;
        # يطبع xdogcatCainAbel
    print sort @george, 'to', @harry;
        # يطبع AbelAxedCainPunishedcatchaseddoggonetoxyz
    # فرز غير فعال عن طريق المقارنة العددية التنازلية باستخدام
    # أول عدد صحيح بعد أول علامة =، أو السجل بأكمله
    # مع عدم الحساسية لحالة الأحرف بخلاف ذلك
    my @new = sort {
        ($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0]
                            ||
                    fc($a)  cmp  fc($b)
    } @old;
    # نفس الشيء، ولكن بكفاءة أكبر؛
    # سنبني فهارس مساعدة بدلاً من ذلك
    # للسرعة
    my (@nums, @caps);
    for (@old) {
        push @nums, ( /=(\d+)/ ? $1 : undef );
        push @caps, fc($_);
    }
    my @new = @old[ sort {
                           $nums[$b] <=> $nums[$a]
                                    ||
                           $caps[$a] cmp $caps[$b]
                         } 0..$#old
                  ];
    # نفس الشيء، ولكن بدون أي متغيرات مؤقتة
    my @new = map { $_->[0] }
           sort { $b->[1] <=> $a->[1]
                           ||
                  $a->[2] cmp $b->[2]
           } map { [$_, /=(\d+)/, fc($_)] } @old;
    # يسمح لك استخدام نموذج أولي باستخدام أي روتين فرعي للمقارنة
    # كروتين فرز (بما في ذلك روتينات الحزم الأخرى)
    package Other;
    sub backwards ($$) { $_[1] cmp $_[0]; }  # لا يتم تعيين $a و $b
                                             # هنا
    package main;
    my @new = sort Other::backwards @old;
    ## استخدام نموذج أولي مع توقيع الدالة
    use feature 'signatures';
    sub function_with_signature :prototype($$) ($one, $two) {
        return $one <=> $two
    }
    my @new = sort function_with_signature @old;
    

تحذير: يلزم توخي الحذر النحوي عند ترتيب القائمة المعادة من دالة. إذا كنت تريد ترتيب القائمة المعادة بواسطة استدعاء الدالة find_records(@key)، فيمكنك استخدام:

    my @contact = sort { $a cmp $b } find_records @key;
    my @contact = sort +find_records(@key);
    my @contact = sort &find_records(@key);
    my @contact = sort(find_records(@key));
    

إذا كنت تريد بدلاً من ذلك ترتيب المصفوفة @key باستخدام روتين المقارنة find_records() فيمكنك استخدام:

    my @contact = sort { find_records() } @key;
    my @contact = sort find_records(@key);
    my @contact = sort(find_records @key);
    my @contact = sort(find_records (@key));
    

يُضبط كل من $a و $b كمتغيرات حزمة عامة (package globals) في الحزمة التي استُدعيت منها sort(). هذا يعني $main::a و $main::b (أو $::a و $::b) في حزمة "main"، و $FooPack::a و $FooPack::b في حزمة "FooPack"، إلخ. إذا كان بلوك الترتيب في نطاق تصريح "my" أو "state" لـ $a و/أو $b، فإنه يجب عليك كتابة الاسم الكامل للمتغيرات في بلوك الترتيب:

   package main;
   my $a = "C"; # خطر، ويل روبنسون، خطر !!!
   print sort { $a cmp $b }               qw(A C E G B D F H);
                                          # خطأ
   sub badlexi { $a cmp $b }
   print sort badlexi                     qw(A C E G B D F H);
                                          # خطأ
   # ما سبق يطبع BACFEDGH أو ترتيبًا غير صحيح آخر
   print sort { $::a cmp $::b }           qw(A C E G B D F H);
                                          # موافق
   print sort { our $a cmp our $b }       qw(A C E G B D F H);
                                          # موافق أيضًا
   print sort { our ($a, $b); $a cmp $b } qw(A C E G B D F H);
                                          # موافق أيضًا
   sub lexi { our $a cmp our $b }
   print sort lexi                        qw(A C E G B D F H);
                                          # موافق أيضًا
   # ما سبق يطبع ABCDEFGH
    

مع العناية المناسبة، يمكنك خلط متغيرات الحزمة ومتغيرات my (أو state) لـ $a و/أو $b:

   my $a = {
      tiny   => -2,
      small  => -1,
      normal => 0,
      big    => 1,
      huge   => 2
   };
   say sort { $a->{our $a} <=> $a->{our $b} }
       qw{ huge normal tiny small big};
   # يطبع tinysmallnormalbighuge
    

يكون كل من $a و $b محليين ضمنيًا لتنفيذ sort() ويستعيدان قيمهما السابقة عند اكتمال عملية الترتيب.

روتينات الفرز الفرعية المكتوبة باستخدام $a و $b مرتبطة بالحزمة المستدعية لها. من الممكن، ولكن بفائدة محدودة، تعريفها في حزمة مختلفة، بما أن الروتين الفرعي يجب أن يظل يشير إلى $a و $b الخاصين بالحزمة المستدعية:

   package Foo;
   sub lexi { $Bar::a cmp $Bar::b }
   package Bar;
   ... sort Foo::lexi ...
    

استخدم الإصدارات ذات النماذج الأولية (prototyped) (انظر أعلاه) للحصول على بديل أكثر عمومية.

يُطلب من دالة المقارنة أن تتصرف بشكل سليم. إذا أعادت نتائج غير متسقة (على سبيل المثال، القول بأن $x[1] أقل من $x[2] أحيانًا وقول العكس أحيانًا أخرى)، فلن تكون النتائج محددة جيدًا.

بما أن "<=>" يعيد "undef" عندما يكون أي من المعاملين "NaN" (ليس رقمًا)، كن حذرًا عند الترتيب باستخدام دالة مقارنة مثل "$a <=> $b" لأي قوائم قد تحتوي على "NaN". يستفيد المثال التالي من حقيقة أن "NaN != NaN" لاستبعاد أي قيم "NaN" من قائمة المدخلات.

    my @result = sort { $a <=> $b } grep { $_ == $_ } @input;
    

في النسخة الحالية من Perl، نُفذت دالة "sort" عبر خوارزمية mergesort.

يزيل العناصر المحددة بواسطة OFFSET و LENGTH من المصفوفة، ويستبدلها بعناصر LIST، إن وجدت. في سياق القائمة، يعيد العناصر التي أُزيلت من المصفوفة. وفي السياق العددي، يعيد آخر عنصر أُزيل، أو "undef" إذا لم تُزل أي عناصر. تنمو المصفوفة أو تتقلص حسب الضرورة. إذا كان OFFSET سالبًا فإنه يبدأ من تلك المسافة من نهاية المصفوفة. إذا حُذف LENGTH، يزيل كل شيء من OFFSET فصاعدًا. إذا كان LENGTH سالبًا، يزيل العناصر من OFFSET فصاعدًا باستثناء عناصر بطول -LENGTH في نهاية المصفوفة. إذا حُذف كل من OFFSET و LENGTH، يزيل كل شيء. إذا كان OFFSET يتجاوز نهاية المصفوفة وقُدم LENGTH، يصدر Perl تحذيرًا، ويقوم بالعملية في نهاية المصفوفة.

تصح المعادلات التالية (بافتراض أن "$#a >= $i"):

    push(@a,$x,$y)      splice(@a,@a,0,$x,$y)
    pop(@a)             splice(@a,-1)
    shift(@a)           splice(@a,0,1)
    unshift(@a,$x,$y)   splice(@a,0,0,$x,$y)
    $a[$i] = $y         splice(@a,$i,1,$y)
    

يمكن استخدام "splice"، على سبيل المثال، لتنفيذ معالجة طابور نونية (n-ary):

    sub nary_print {
      my $n = shift;
      while (my @next_n = splice @_, 0, $n) {
        say join q{ -- }, @next_n;
      }
    }
    nary_print(3, qw(a b c d e f g h));
    # يطبع:
    #   a -- b -- c
    #   d -- e -- f
    #   g -- h
    

بدءًا من الإصدار Perl 5.14، سمحت ميزة تجريبية لـ "splice" بأخذ تعبير عددي. وقد اعتبرت هذه التجربة غير ناجحة، وأزيلت اعتبارًا من Perl 5.24.

split /PATTERN/,EXPR,LIMIT
split /PATTERN/,EXPR
split /PATTERN/
يقسم السلسلة النصية EXPR إلى قائمة من السلاسل النصية ويعيد القائمة في سياق القائمة، أو حجم القائمة في السياق العددي. (قبل Perl 5.11، كان يقوم أيضًا بالكتابة فوق @_ بالقائمة في السياق الخالي والعددي. إذا كنت تستهدف إصدارات perl قديمة، فاحذر.)

إذا أُعطي PATTERN فقط، فإن EXPR تكون قيمتها المبدئية $_.

أي شيء في EXPR يطابق PATTERN يُعتبر فاصلاً يفصل EXPR إلى سلاسل فرعية (تسمى "fields") لا تتضمن الفاصل. لاحظ أن الفاصل قد يكون أطول من حرف واحد أو حتى لا يحتوي على أحرف على الإطلاق (السلسلة الفارغة، وهي مطابقة صفرية العرض).

ليس من الضروري أن يكون PATTERN ثابتًا؛ يمكن استخدام تعبير لتحديد نمط يتغير في وقت التشغيل.

إذا طابق PATTERN السلسلة الفارغة، فسيتم تقسيم EXPR عند موضع المطابقة (بين الأحرف). كمثال، ما يلي:

    my @x = split(/b/, "abc"); # ("a", "c")
    

يستخدم "b" في 'abc' كفاصل لإنتاج القائمة ("a", "c"). ومع ذلك، فإن هذا:

    my @x = split(//, "abc"); # ("a", "b", "c")
    

يستخدم مطابقات السلسلة الفارغة كفواصل؛ وبالتالي، يمكن استخدام السلسلة الفارغة لتقسيم EXPR إلى قائمة بمكوناتها من الأحرف.

كحالة خاصة لـ "split"PATTERN/,EXPR,LIMIT>، النمط الفارغ المعطى في صيغة عامل المطابقة ("//") يطابق تحديداً السلسلة الفارغة، وهو ما يتعارض مع تفسيره المعتاد كآخر مطابقة ناجحة.

إذا كان PATTERN هو "/^/"، فسيُعامل كما لو أنه استخدم معدل السطور المتعددة ("/^/m")، لأنه ليس ذو فائدة كبيرة بخلاف ذلك.

يمكن تحديد "/m" وأي من معدلات الأنماط الأخرى الصالحة لـ "qr" (الملخصة في "qr/STRING/msixpodualn" في perlop) بشكل صريح.

كحالة خاصة أخرى، يحاكي "split"PATTERN/,EXPR,LIMIT> السلوك المبدئي لأداة سطر الأوامر awk عندما يكون PATTERN إما محذوفاً أو سلسلة نصية مكونة من مسافة واحدة (مثل ' ' أو "\x20"، ولكن ليس مثلاً "/ /"). في هذه الحالة، تُزال أي مسافات بيضاء بادئة في EXPR قبل حدوث التقسيم، ويُعامل PATTERN بدلاً من ذلك كما لو كان "/\s+/"؛ وعلى وجه الخصوص، هذا يعني أن أي مسافة بيضاء متصلة (وليس مجرد مسافة واحدة) تُستخدم كفاصل.

    my @x = split(" ", "  Quick brown fox\n");
    # ("Quick", "brown", "fox")
    my @x = split(" ", "RED\tGREEN\tBLUE");
    # ("RED", "GREEN", "BLUE")
    

استخدام split بهذا الأسلوب يشبه إلى حد كبير طريقة عمل "qw//".

ومع ذلك، يمكن تجنب هذه المعالجة الخاصة بتحديد النمط "/ /" بدلاً من السلسلة " "، وبالتالي السماح لحرف مسافة واحد فقط بأن يكون فاصلاً. في إصدارات Perl الأقدم، كانت هذه الحالة الخاصة مقتصرة على استخدام " " صريحة كمعامل نمط لـ split؛ وفي Perl 5.18.0 وما بعده، تُفعّل هذه الحالة الخاصة بواسطة أي تعبير ينتج عنه السلسلة البسيطة " ".

بدءاً من Perl 5.28، يعمل تقسيم المسافات البيضاء في هذه الحالة الخاصة كما هو متوقع في نطاق "use feature 'unicode_strings'". في الإصدارات السابقة، وخارج نطاق هذه الميزة، يظهر فيه "خطأ يونيكود" "Unicode Bug" في perlunicode: يمكن معاملة المحارف التي تعتبر مسافات بيضاء وفقاً لقواعد يونيكود ولكن ليس وفقاً لقواعد ASCII كجزء من الحقول بدلاً من كونها فواصل للحقول، اعتماداً على الترميز الداخلي للسلسلة النصية.

بدءاً من Perl 5.39.9، المبدئي "/x" لا يؤثر على "split STRING" ولكنه يؤثر على "split PATTERN"، وهذا يعني أن "split " "" سينتج محاكاة awk المتوقعة بغض النظر عما إذا كان يُستخدم في نطاق جملة "use re "/x"". إذا كنت تريد التقسيم حسب المسافات تحت "use re "/x""، فيجب عليك فعل شيء مثل "split /(?-x: )/" أو "split /\x{20}/" بدلاً من "split / /".

إذا حُذف، فإن PATTERN يكون مبدئيًا حرف مسافة واحد، " "، مما يفعل محاكاة awk الموصوفة مسبقًا.

إذا حُدد LIMIT وكان موجبًا، فإنه يمثل الحد الأقصى لعدد الحقول التي يمكن تقسيم EXPR إليها؛ بعبارة أخرى، LIMIT هو أكبر بواحد من الحد الأقصى لعدد المرات التي يمكن فيها تقسيم EXPR. وبالتالي، فإن قيمة LIMIT التي تبلغ 1 تعني أن EXPR يمكن تقسيمها بحد أقصى صفر من المرات، مما ينتج عنه حقل واحد كحد أقصى (وهو القيمة الكاملة لـ EXPR). على سبيل المثال:

    my @x = split(/,/, "a,b,c", 1); # ("a,b,c")
    my @x = split(/,/, "a,b,c", 2); # ("a", "b,c")
    my @x = split(/,/, "a,b,c", 3); # ("a", "b", "c")
    my @x = split(/,/, "a,b,c", 4); # ("a", "b", "c")
    

إذا كان LIMIT سالبًا، فإنه يُعامل كما لو كان كبيرًا بشكل تعسفي؛ ويتم إنتاج أكبر عدد ممكن من الحقول.

إذا حُذف LIMIT (أو كان صفرًا، وهو ما يعادله)، فإنه يُعامل عادةً كما لو كان سالبًا ولكن مع استثناء أن الحقول الفارغة اللاحقة تُحذف (الحقول البادئة الفارغة تُحفظ دائمًا)؛ إذا كانت جميع الحقول فارغة، فإن جميع الحقول تُعتبر لاحقة (وبالتالي تُحذف في هذه الحالة). وبالتالي، فإن ما يلي:

    my @x = split(/,/, "a,b,c,,,"); # ("a", "b", "c")
    

ينتج قائمة من ثلاثة عناصر فقط.

    my @x = split(/,/, "a,b,c,,,", -1); # ("a", "b", "c", "", "", "")
    

ينتج قائمة من ستة عناصر.

في التطبيقات التي يكون فيها الوقت حرجًا، من الجدير بالاهتمام تجنب التقسيم إلى حقول أكثر مما هو ضروري. وبالتالي، عند التعيين إلى قائمة، إذا حُذف LIMIT (أو كان صفرًا)، فسيُعامل LIMIT كما لو كان أكبر بواحد من عدد المتغيرات في القائمة؛ فيما يلي، يكون LIMIT ضمنيًا هو 3:

    my ($login, $passwd) = split(/:/);
    

لاحظ أن تقسيم EXPR التي تؤول إلى سلسلة فارغة ينتج دائمًا صفرًا من الحقول، بغض النظر عن LIMIT المحدد.

يتم إنتاج حقل بادئ فارغ عندما تكون هناك مطابقة موجبة العرض في بداية EXPR. على سبيل المثال:

    my @x = split(/ /, " abc"); # ("", "abc")
    

ينقسم إلى عنصرين. ومع ذلك، فإن مطابقة صفرية العرض في بداية EXPR لا تنتج حقلًا فارغًا أبدًا، بحيث أن:

    my @x = split(//, " abc"); # (" ", "a", "b", "c")
    

ينقسم إلى أربعة عناصر بدلاً من خمسة.

ومن ناحية أخرى، يتم إنتاج حقل لاحق فارغ عندما تكون هناك مطابقة في نهاية EXPR، بغض النظر عن طول المطابقة (بالطبع، ما لم يُعطَ LIMIT غير صفري بشكل صريح، فسيتم حذف هذه الحقول، كما في المثال الأخير). وبالتالي:

    my @x = split(//, " abc", -1); # (" ", "a", "b", "c", "")
    

إذا كان PATTERN يحتوي على مجموعات التقاط (capturing groups)، فإنه لكل فاصل، يتم إنتاج حقل إضافي لكل سلسلة فرعية التقطتها مجموعة (بالترتيب الذي حُددت به المجموعات، وفقًا للمراجع الخلفية)؛ إذا لم تتطابق أي مجموعة، فإنها تلتقط قيمة "undef" بدلاً من سلسلة فرعية. لاحظ أيضًا أن أي حقل إضافي من هذا القبيل يتم إنتاجه كلما وجد فاصل (أي كلما حدث تقسيم)، وهذا الحقل الإضافي لا يُحتسب ضمن LIMIT. تأمل التعبيرات التالية المقيمة في سياق القائمة (كل قائمة معادة موضحة في التعليق المرتبط بها):

    my @x = split(/-|,/    , "1-10,20", 3);
    # ("1", "10", "20")
    my @x = split(/(-|,)/  , "1-10,20", 3);
    # ("1", "-", "10", ",", "20")
    my @x = split(/-|(,)/  , "1-10,20", 3);
    # ("1", undef, "10", ",", "20")
    my @x = split(/(-)|,/  , "1-10,20", 3);
    # ("1", "-", "10", undef, "20")
    my @x = split(/(-)|(,)/, "1-10,20", 3);
    # ("1", "-", undef, "10", undef, ",", "20")
    
يعيد سلسلة نصية منسقة حسب اصطلاحات "printf" المعتادة لدالة مكتبة C المسماة "sprintf". راجع أدناه لمزيد من التفاصيل وراجع sprintf(3) أو printf(3) على نظامك للحصول على شرح للمبادئ العامة.

على سبيل المثال:

        # تنسيق الرقم مع ما يصل إلى 8 أصفار بادئة
        my $result = sprintf("%08d", $number);
        # تقريب الرقم إلى 3 خانات بعد الفاصلة العشرية
        my $rounded = sprintf("%.3f", $number);
    

تقوم Perl بتنسيق "sprintf" الخاص بها: فهي تحاكي دالة C المسماة sprintf(3)، لكنها لا تستخدمها إلا للأرقام ذات الفاصلة العائمة، وحتى في هذه الحالة لا يُسمح إلا بالمعدلات القياسية. وبالتالي فإن الامتدادات غير القياسية في sprintf(3) المحلية لديك غير متاحة من Perl.

على عكس "printf"، فإن "sprintf" لا يفعل ما تقصده على الأرجح عندما تمرر له مصفوفة كمعامل أول. تُعطى المصفوفة سياقًا عدديًا، وبدلاً من استخدام العنصر رقم 0 في المصفوفة كشكل للتنسيق، سيستخدم Perl عدد العناصر في المصفوفة كشكل للتنسيق، وهو أمر نادرًا ما يكون مفيدًا.

تسمح "sprintf" في Perl بالتحويلات التالية المعروفة عالمياً:

   %%    علامة النسبة المئوية
   %c    حرف بالرقم المعطى
   %s    سلسلة نصية
   %d    عدد صحيح بإشارة، بالنظام العشري
   %u    عدد صحيح بدون إشارة، بالنظام العشري
   %o    عدد صحيح بدون إشارة، بالنظام الثماني
   %x    عدد صحيح بدون إشارة، بالنظام الست عشري
   %e    رقم بفاصلة عائمة، بالترميز العلمي
   %f    رقم بفاصلة عائمة، بترميز عشري ثابت
   %g    رقم بفاصلة عائمة، بترميز %e أو %f
    

بالإضافة إلى ذلك، يسمح Perl بالتحويلات المدعومة على نطاق واسع التالية:

   %X    مثل %x، ولكن باستخدام أحرف كبيرة
   %E    مثل %e، ولكن باستخدام حرف "E" كبير
   %G    مثل %g، ولكن مع حرف "E" كبير (إذا كان متاحًا)
   %b    عدد صحيح بدون إشارة، بالنظام الثنائي
   %B    مثل %b، ولكن باستخدام حرف "B" كبير مع علم #
   %p    مؤشر (يخرج عنوان قيمة Perl بالنظام الست عشري)
   %n    خاص: *يخزن* عدد الأحرف المخرجة حتى الآن
         في المعامل التالي في قائمة المعاملات
   %a    فاصلة عائمة ست عشرية
   %A    مثل %a، ولكن باستخدام أحرف كبيرة
   %i    مرادف لـ %d
   %D    مرادف لـ %ld
   %U    مرادف لـ %lu
   %O    مرادف لـ %lo
   %F    مرادف لـ %f
    

لاحظ أن عدد أرقام الأس في الترميز العلمي الناتج عن %e و %E و %g و %G للأرقام التي يكون فيها معيار الأس أقل من 100 يعتمد على النظام: فقد يكون ثلاثة أرقام أو أقل (مع حشو بالأصفار حسب الضرورة). بعبارة أخرى، 1.23 في عشرة أس 99 قد تكون إما "1.23e99" أو "1.23e099". وبالمثل بالنسبة لـ %a و %A: قد يتغير الأس أو الأرقام الست عشرية: خاصة خيار ضبط Perl لـ "long doubles" قد يسبب مفاجآت.

بين "%" وحرف التنسيق، يمكنك تحديد عدة سمات إضافية تتحكم في تفسير التنسيق. وهي بالترتيب:

فهرس معامل التنسيق
فهرس معامل تنسيق صريح، مثل "2$". مبدئيًا، سيقوم sprintf بتنسيق المعامل التالي غير المستخدم في القائمة، ولكن هذا يسمح لك بأخذ المعاملات خارج ترتيبها:

  printf '%2$d %1$d', 12, 34;      # يطبع "34 12"
  printf '%3$d %d %1$d', 1, 2, 3;  # يطبع "3 1 1"
    
واحد أو أكثر من:

   مسافة   سابقة للأرقام غير السالبة بمسافة
   +       سابقة للأرقام غير السالبة بعلامة زائد
   -       محاذاة إلى اليسار داخل الحقل
   0       استخدام الأصفار، وليس المسافات، للمحاذاة إلى اليمين
   #       ضمان وجود "0" بادئة لأي رقم ثماني،
           سابقة للأرقام الست عشرية غير الصفرية بـ "0x" أو "0X"،
           سابقة للأرقام الثنائية غير الصفرية بـ "0b" أو "0B"
    

على سبيل المثال:

  printf '<% d>',  12;   # يطبع "< 12>"
  printf '<% d>',   0;   # يطبع "< 0>"
  printf '<% d>', -12;   # يطبع "<-12>"
  printf '<%+d>',  12;   # يطبع "<+12>"
  printf '<%+d>',   0;   # يطبع "<+0>"
  printf '<%+d>', -12;   # يطبع "<-12>"
  printf '<%6s>',  12;   # يطبع "<    12>"
  printf '<%-6s>', 12;   # يطبع "<12    >"
  printf '<%06s>', 12;   # يطبع "<000012>"
  printf '<%#o>',  12;   # يطبع "<014>"
  printf '<%#x>',  12;   # يطبع "<0xc>"
  printf '<%#X>',  12;   # يطبع "<0XC>"
  printf '<%#b>',  12;   # يطبع "<0b1100>"
  printf '<%#B>',  12;   # يطبع "<0B1100>"
    

عند إعطاء مسافة وعلامة زائد كأعلام في آن واحد، تُتجاهل المسافة.

  printf '<%+ d>', 12;   # يطبع "<+12>"
  printf '<% +d>', 12;   # يطبع "<+12>"
    

عند إعطاء علم # ودقة في تحويل %o، تُزاد الدقة إذا كان ذلك ضرورياً للصفر البادئ "0".

  printf '<%#.5o>', 012;      # يطبع "<00012>"
  printf '<%#.5o>', 012345;   # يطبع "<012345>"
  printf '<%#.0o>', 0;        # يطبع "<0>"
    
علم المتجه
يخبر هذا العلم Perl بتفسير السلسلة النصية المزودة كمتجه من الأعداد الصحيحة، واحد لكل محرف في السلسلة. تطبق Perl التنسيق على كل عدد صحيح بدورها، ثم تجمع السلاسل الناتجة بفاصل (نقطة "." افتراضياً). يمكن أن يكون هذا مفيداً لعرض القيم الترتيبية للمحارف في سلاسل نصية عشوائية:

  printf "%vd", "AB\x{100}";           # يطبع "65.66.256"
  printf "version is v%vd\n", $^V;     # إصدار Perl
    

ضع نجمة "*" قبل "v" لتجاوز السلسلة النصية المستخدمة لفصل الأرقام:

  printf "address is %*vX\n", ":", $addr;   # عنوان IPv6
  printf "bits are %0*v8b\n", " ", $bits;   # سلسلة بتات عشوائية
    

يمكنك أيضاً تحديد رقم الوسيط صراحة لاستخدامه كسلسلة ربط باستخدام شيء مثل "*2$v"؛ على سبيل المثال:

  printf '%*4$vX %*4$vX %*4$vX',       # 3 عناوين IPv6
          @addr[1..3], ":";
    
العرض (الأدنى)
تُنسق الوسائط عادةً لتكون بالعرض المطلوب فقط لعرض القيمة المعطاة. يمكنك تجاوز العرض بوضع رقم هنا، أو الحصول على العرض من الوسيط التالي (باستخدام "*") أو من وسيط محدد (مثلاً، باستخدام "*2$"):

 printf "<%s>", "a";       # يطبع "<a>"
 printf "<%6s>", "a";      # يطبع "<     a>"
 printf "<%*s>", 6, "a";   # يطبع "<     a>"
 printf '<%*2$s>', "a", 6; # يطبع "<     a>"
 printf "<%2s>", "long";   # يطبع "<long>" (لا يقتطع)
    

إذا كان عرض الحقل الذي تم الحصول عليه من خلال "*" سالباً، فله نفس تأثير العلم "-": المحاذاة إلى اليسار.

الدقة، أو العرض الأقصى
يمكنك تحديد دقة (للتحويلات الرقمية) أو عرض أقصى (للتحويلات النصية) عن طريق تحديد "." متبوعة برقم. بالنسبة لتنسيقات الفاصلة العائمة باستثناء "g" و "G"، يحدد هذا عدد الخانات التي تظهر على يمين العلامة العشرية (الافتراضي هو 6). على سبيل المثال:

  # تخضع هذه الأمثلة للاختلافات الخاصة بالنظام
  printf '<%f>', 1;       # يطبع "<1.000000>"
  printf '<%.1f>', 1;     # يطبع "<1.0>"
  printf '<%.0f>', 1;     # يطبع "<1>"
  printf '<%07.2f>', 1.3; # يطبع "<0001.30>"
  printf '<%e>', 10;      # يطبع "<1.000000e+01>"
  printf '<%.1e>', 10;    # يطبع "<1.0e+01>"
    

بالنسبة لـ "g" و "G"، يحدد هذا الحد الأقصى لعدد الأرقام المعنوية المراد عرضها؛ على سبيل المثال:

  # تخضع هذه الأمثلة للاختلافات الخاصة بالنظام.
  printf '<%g>', 1;        # يطبع "<1>"
  printf '<%.10g>', 1;     # يطبع "<1>"
  printf '<%g>', 100;      # يطبع "<100>"
  printf '<%.1g>', 100;    # يطبع "<1e+02>"
  printf '<%.2g>', 100.01; # يطبع "<1e+02>"
  printf '<%.5g>', 100.01; # يطبع "<100.01>"
  printf '<%.4g>', 100.01; # يطبع "<100>"
  printf '<%.1g>', 0.0111; # يطبع "<0.01>"
  printf '<%.2g>', 0.0111; # يطبع "<0.011>"
  printf '<%.3g>', 0.0111; # يطبع "<0.0111>"
    

بالنسبة لتحويلات الأعداد الصحيحة، يعني تحديد الدقة أن مخرجات الرقم نفسه يجب أن تُحشى بالأصفار حتى هذا العرض، حيث يتم تجاهل العلم 0:

  printf '<%.6d>', 1;      # يطبع "<000001>"
  printf '<%+.6d>', 1;     # يطبع "<+000001>"
  printf '<%-10.6d>', 1;   # يطبع "<000001    >"
  printf '<%10.6d>', 1;    # يطبع "<    000001>"
  printf '<%010.6d>', 1;   # يطبع "<    000001>"
  printf '<%+10.6d>', 1;   # يطبع "<   +000001>"
  printf '<%.6x>', 1;      # يطبع "<000001>"
  printf '<%#.6x>', 1;     # يطبع "<0x000001>"
  printf '<%-10.6x>', 1;   # يطبع "<000001    >"
  printf '<%10.6x>', 1;    # يطبع "<    000001>"
  printf '<%010.6x>', 1;   # يطبع "<    000001>"
  printf '<%#10.6x>', 1;   # يطبع "<  0x000001>"
    

بالنسبة لتحويلات السلاسل النصية، يؤدي تحديد الدقة إلى اقتطاع السلسلة لتناسب العرض المحدد:

  printf '<%.5s>', "truncated";   # يطبع "<trunc>"
  printf '<%10.5s>', "truncated"; # يطبع "<     trunc>"
    

يمكنك أيضاً الحصول على الدقة من الوسيط التالي باستخدام ".*"، أو من وسيط محدد (مثلاً، باستخدام ".*2$"):

  printf '<%.6x>', 1;       # يطبع "<000001>"
  printf '<%.*x>', 6, 1;    # يطبع "<000001>"
  printf '<%.*2$x>', 1, 6;  # يطبع "<000001>"
  printf '<%6.*2$x>', 1, 4; # يطبع "<  0001>"
    

إذا كانت الدقة التي تم الحصول عليها من خلال "*" سالبة، فإنها تُعتبر بمثابة عدم وجود دقة على الإطلاق.

  printf '<%.*s>',  7, "string";   # يطبع "<string>"
  printf '<%.*s>',  3, "string";   # يطبع "<str>"
  printf '<%.*s>',  0, "string";   # يطبع "<>"
  printf '<%.*s>', -1, "string";   # يطبع "<string>"
  printf '<%.*d>',  1, 0;   # يطبع "<0>"
  printf '<%.*d>',  0, 0;   # يطبع "<>"
  printf '<%.*d>', -1, 0;   # يطبع "<0>"
    
الحجم
بالنسبة للتحويلات الرقمية، يمكنك تحديد الحجم لتفسير الرقم باستخدامه باستخدام "l"، أو "h"، أو "V"، أو "q"، أو "L"، أو "ll". بالنسبة لتحويلات الأعداد الصحيحة ("d u o x X b i D U O")، يُفترض عادةً أن تكون الأرقام بأي حجم عدد صحيح مبدئي على منصتك (عادةً 32 أو 64 بت)، ولكن يمكنك تجاوز ذلك لاستخدام أحد أنواع C القياسية بدلاً من ذلك، كما يدعمها المترجم المستخدم لبناء Perl:

   hh          تفسير العدد الصحيح كنوع C "char" أو "unsigned
               char" في Perl 5.14 أو الأحدث
   h           تفسير العدد الصحيح كنوع C "short" أو
               "unsigned short"
   j           تفسير العدد الصحيح كنوع C "intmax_t" في Perl
               5.14 أو الأحدث. قبل Perl 5.30 كان هذا يعمل فقط
               مع مترجم C99، وبالتالي لم يكن قابلاً للنقل قبل
               ذلك الإصدار.
   l           تفسير العدد الصحيح كنوع C "long" أو
               "unsigned long"
   q, L, or ll تفسير العدد الصحيح كنوع C "long long"،
               أو "unsigned long long"، أو "quad" (عادةً
               أعداد صحيحة 64-بت)
   t           تفسير العدد الصحيح كنوع C "ptrdiff_t" في Perl
               5.14 أو الأحدث
   z           تفسير العدد الصحيح كأنواع C "size_t" أو
               "ssize_t" في Perl 5.14 أو الأحدث
    

لاحظ أنه، بشكل عام، استخدام المعدل "l" (على سبيل المثال، عند كتابة "%ld" أو "%lu" بدلاً من "%d" و "%u") غير ضروري عند استخدامه من كود Perl. علاوة على ذلك، قد يكون ضاراً، على سبيل المثال في Windows 64-بت حيث يكون long بحجم 32-بت.

اعتباراً من 5.14، لا يثير أي من هذه استثناءً إذا لم تكن مدعومة على منصتك. ومع ذلك، إذا كانت التحذيرات مفعلة، فسيتم إصدار تحذير من فئة تحذير "printf" عند استخدام علم تحويل غير مدعوم. إذا كنت تفضل بدلاً من ذلك استثناءً، فافعل ذلك:

    use warnings FATAL => "printf";
    

إذا كنت تود معرفة الاعتمادية على الإصدار قبل البدء في تشغيل البرنامج، فضع شيئاً كهذا في أعلاه:

    use v5.14;  # لمعدلات printf hh/j/t/z/
    

يمكنك معرفة ما إذا كانت نسخة Perl الخاصة بك تدعم quads عبر Config:

    use Config;
    if ($Config{use64bitint} eq "define"
        || $Config{longsize} >= 8) {
        print "Nice quads!\n";
    }
    

بالنسبة لتحويلات الفاصلة العائمة ("e f g E F G")، يُفترض عادةً أن تكون الأرقام بحجم الفاصلة العائمة المبدئي على منصتك (double أو long double)، ولكن يمكنك فرض استخدام "long double" مع "q" أو "L" أو "ll" إذا كانت منصتك تدعمها. يمكنك معرفة ما إذا كانت نسخة Perl الخاصة بك تدعم long doubles عبر Config:

    use Config;
    print "long doubles\n" if $Config{d_longdbl} eq "define";
    

يمكنك معرفة ما إذا كانت Perl تعتبر "long double" هو حجم الفاصلة العائمة المبدئي للاستخدام على منصتك عبر Config:

    use Config;
    if ($Config{uselongdouble} eq "define") {
        print "long doubles by default\n";
    }
    

قد يكون أيضاً أن long doubles و doubles هما نفس الشيء:

        use Config;
        ($Config{doublesize} == $Config{longdblsize}) &&
                print "doubles are long doubles\n";
    

محدد الحجم "V" ليس له أي تأثير على كود Perl، ولكنه مدعوم للتوافق مع كود XS. وهو يعني "استخدام الحجم القياسي لعدد صحيح أو رقم فاصلة عائمة في Perl"، وهو الوضع الافتراضي.

ترتيب الوسائط
عادةً، تأخذ "sprintf" الوسيط غير المستخدم التالي كقيمة للتنسيق لكل مواصفة تنسيق. إذا كانت مواصفة التنسيق تستخدم "*" لطلب وسائط إضافية، فتُستهلك هذه من قائمة الوسائط بالترتيب الذي تظهر به في مواصفة التنسيق قبل القيمة المراد تنسيقها. عندما يتم تحديد وسيط بفهرس صريح، فإن هذا لا يؤثر على الترتيب الطبيعي للوسائط، حتى عندما يكون الفهرس المحدد صراحة هو الوسيط التالي.

لذا:

    printf "<%*.*s>", $x, $y, $z;
    

تستخدم $x للعرض، و $y للدقة، و $z كقيمة للتنسيق؛ بينما:

  printf '<%*1$.*s>', $x, $y;
    

ستستخدم $x للعرض والدقة، و $y كقيمة للتنسيق.

فيما يلي بعض الأمثلة الإضافية؛ انتبه إلى أنه عند استخدام فهرس صريح، قد تحتاج علامة "$" إلى الهروب:

 printf "%2\$d %d\n",      12, 34;     # سيطبع "34 12\n"
 printf "%2\$d %d %d\n",   12, 34;     # سيطبع "34 12 34\n"
 printf "%3\$d %d %d\n",   12, 34, 56; # سيطبع "56 12 34\n"
 printf "%2\$*3\$d %d\n",  12, 34,  3; # سيطبع " 34 12\n"
 printf "%*1\$.*f\n",       4,  5, 10; # سيطبع "5.0000\n"
    

إذا كان "use locale" (بما في ذلك "use locale ':not_characters'") ساري المفعول وتم استدعاء "POSIX::setlocale"، فإن المحرف المستخدم كفاصل عشري في أرقام الفاصلة العائمة المنسقة يتأثر بالمحلية "LC_NUMERIC". انظر perllocale و POSIX.

sqrt EXPR
تعيد الجذر التربيعي الموجب لـ EXPR. إذا حُذف EXPR، تُستخدم $_. تعمل فقط للمعاملات غير السالبة ما لم تكن قد حمّلت وحدة "Math::Complex" النمطية.

    use Math::Complex;
    print sqrt(-4);    # يطبع 2i
    
srand EXPR
تضبط وتُرجع بذرة الأرقام العشوائية لمعامل "rand".

الغرض من الدالة هو "بذر" دالة "rand" بحيث يمكن لـ "rand" إنتاج تسلسل مختلف في كل مرة تقوم فيها بتشغيل برنامجك. عند استدعائها مع معلمة، تستخدم "srand" تلك المعلمة كبذرة؛ وإلا فإنها تختار بذرة بشكل (شبه) عشوائي (انظر أدناه). في كلتا الحالتين، بدءاً من Perl 5.14، فإنها تُرجع البذرة. للإشارة إلى أن الكود الخاص بك سيعمل فقط على نسخ Perl الحديثة:

    use v5.14;  # لكي تُرجع srand البذرة
    

إذا لم يتم استدعاء "srand" صراحة، فسيتم استدعاؤها ضمنياً بدون معلمة عند أول استخدام لمعامل "rand". ومع ذلك، هناك حالات قليلة من المرجح أن ترغب فيها البرامج في استدعاء "srand". إحداها لتوليد نتائج يمكن التنبؤ بها، بشكل عام للاختبار أو التنقيب. هناك، تستخدم srand($seed)، بنفس $seed في كل مرة. حالة أخرى هي أنك قد ترغب في استدعاء "srand" بعد "fork" لتجنب مشاركة العمليات الابنة لنفس قيمة البذرة مثل العملية الأب (وبالتالي بعضها البعض).

لا تستدعِ srand() (أي بدون وسيط) أكثر من مرة في كل عملية. يجب أن تحتوي الحالة الداخلية لمولد الأرقام العشوائية على اعتلاج أكثر مما يمكن توفيره بواسطة أي بذرة، لذا فإن استدعاء "srand" مرة أخرى في الواقع يفقدنا العشوائية.

معظم تطبيقات "srand" تأخذ عدداً صحيحاً وتقوم بصمت باقتطاع الأرقام العشرية. وهذا يعني أن srand(42) ستنتج عادةً نفس النتائج مثل srand(42.1). لكي تكون آمناً، مرر دائماً لـ "srand" عدداً صحيحاً.

الاستخدام النموذجي للبذرة المرتجعة هو لبرنامج اختبار يحتوي على عدد كبير جداً من التوليفات التي لا يمكن اختبارها بشكل شامل في الوقت المتاح له في كل تشغيل. يمكنه اختبار مجموعة فرعية عشوائية في كل مرة، وإذا حدث فشل، يسجل البذرة المستخدمة لذلك التشغيل بحيث يمكن استخدامها لاحقاً لإعادة إنتاج نفس النتائج.

إذا تم ضبط متغير البيئة "PERL_RAND_SEED" على عدد صحيح غير سالب أثناء بدء العملية، فإن استدعاءات srand() بدون وسائط ستقوم بتهيئة مولد الأرقام العشوائية في perl ببذرة ثابتة في كل مرة يتم استدعاؤها فيها، سواء تم استدعاؤها صراحة بدون وسائط أو ضمنياً عبر استخدام rand(). البذر الدقيق الذي سينتجه متغير "PERL_RAND_SEED" معين غير محدد عمدًا، ولكن استخدام قيم مختلفة لـ "PERL_RAND_SEED" يجب أن ينتج نتائج مختلفة. هذا مخصص للتنقيح وتحليل الأداء ويضمن فقط إنتاج نتائج متسقة بين استدعاءات نفس ملف perl التنفيذي الذي يشغل نفس الكود عندما تكون جميع العوامل الأخرى متساوية. يُقرأ متغير البيئة مرة واحدة فقط أثناء بدء العملية، وتغييره أثناء سير البرنامج لن يؤثر على العملية الجارية حالياً. انظر perlrun لمزيد من التفاصيل.

"rand" ليست آمنة تشفيرياً. يجب ألا تعتمد عليها في المواقف الحساسة أمنياً. انظر وثائق "rand" للحصول على قائمة بالبدائل المناسبة.

stat FILEHANDLE
stat EXPR
stat DIRHANDLE
تُرجع قائمة من 13 عنصراً تعطي معلومات الحالة لملف ما، سواء كان الملف مفتوحاً عبر FILEHANDLE أو DIRHANDLE، أو مسمى بواسطة EXPR. إذا تم حذف EXPR، فإنها تجلب حالة $_ (وليس "_"!). تُرجع قائمة فارغة إذا فشلت "stat". تُستخدم عادةً على النحو التالي:

    my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
        $atime,$mtime,$ctime,$blksize,$blocks)
           = stat($filename);
    

ليست كل الحقول مدعومة في جميع أنواع أنظمة الملفات. فيما يلي معاني الحقول:

  0 dev      رقم جهاز نظام الملفات
  1 ino      رقم inode
  2 mode     وضع الملف (النوع والأذونات)
  3 nlink    عدد الوصلات (الصلبة) للملف
  4 uid      معرف المستخدم الرقمي لمالك الملف
  5 gid      معرف المجموعة الرقمي لمالك الملف
  6 rdev     معرف الجهاز (للملفات الخاصة فقط)
  7 size     الحجم الإجمالي للملف بالبايتات
  8 atime    وقت آخر وصول بالثواني منذ epoch
  9 mtime    وقت آخر تعديل بالثواني منذ epoch
 10 ctime    وقت تغيير inode بالثواني منذ epoch (*)
 11 blksize  حجم الإدخال/الإخراج المفضل بالبايتات للتعامل مع
             الملف (قد يختلف من ملف لآخر)
 12 blocks   العدد الفعلي للكتل المخصصة على القرص والخاصة بالنظام
             (غالباً ما تكون 512 بايت لكل منها، ولكن ليس دائماً)
    

(كان تاريخ epoch في الساعة 00:00 يوم 1 يناير 1970 بتوقيت جرينتش.)

(*) ليست كل الحقول مدعومة في جميع أنواع أنظمة الملفات. والجدير بالذكر أن حقل ctime غير محمول. على وجه الخصوص، لا يمكنك توقع أن يكون "وقت الإنشاء"؛ انظر "الملفات وأنظمة الملفات" في perlport لمزيد من التفاصيل.

إذا تم تمرير مقبض ملف خاص يتكون من خط سفلي إلى "stat"، فلن يتم إجراء أي stat، ولكن سيتم إرجاع المحتويات الحالية لهيكل stat من آخر استدعاء لـ "stat" أو "lstat" أو اختبار ملف. مثال:

    if (-x $file && (($d) = stat(_)) && $d < 0) {
        print "$file is executable NFS file\n";
    }
    

(يعمل هذا فقط على الأجهزة التي يكون رقم الجهاز فيها سالباً تحت NFS.)

في بعض المنصات، تكون أرقام inode من نوع أكبر مما تعرف Perl كيفية التعامل معه كقيم عددية صحيحة. إذا لزم الأمر، سيتم إرجاع رقم inode كسلسلة عشرية من أجل الحفاظ على القيمة الكاملة. إذا استُخدم في سياق عددي، فسيتم تحويله إلى قيمة عددية بفاصلة عائمة مع التقريب، وهو مصير من الأفضل تجنبه. لذلك، يجب أن تفضل مقارنة أرقام inode باستخدام "eq" بدلاً من "==". ستعمل "eq" بشكل جيد مع أرقام inode الممثلة عددياً، وكذلك تلك الممثلة كسلاسل نصية.

بما أن الوضع يحتوي على كل من نوع الملف وأذوناته، يجب عليك حجب جزء نوع الملف واستخدام (s)printf مع "%o" إذا كنت تريد رؤية الأذونات الحقيقية.

    my $mode = (stat($filename))[2];
    printf "Permissions are %04o\n", $mode & 07777;
    

في السياق العددي، تُرجع "stat" قيمة منطقية تشير إلى النجاح أو الفشل، وإذا نجحت، فإنها تضبط المعلومات المرتبطة بمقبض الملف الخاص "_".

توفر وحدة File::stat آلية وصول مريحة حسب الاسم:

    use File::stat;
    my $sb = stat($filename);
    printf "File is %s, size is %s, perm %04o, mtime %s\n",
           $filename, $sb->size, $sb->mode & 07777,
           scalar localtime $sb->mtime;
    

يمكنك استيراد ثوابت الوضع الرمزية والدوال ("S_I*") من وحدة Fcntl:

    use Fcntl ':mode';
    my $mode = (stat($filename))[2];
    my $user_rwx      = ($mode & S_IRWXU) >> 6;
    my $group_read    = ($mode & S_IRGRP) >> 3;
    my $other_execute =  $mode & S_IXOTH;
    printf "Permissions are %04o\n", S_IMODE($mode), "\n";
    my $is_setuid     =  $mode & S_ISUID;
    my $is_directory  =  S_ISDIR($mode);
    

يمكنك كتابة الأخيرين باستخدام معاملات "-u" و "-d". ثوابت "S_I*" المتوفرة بشكل شائع هي:

    # الأذونات: قراءة، كتابة، تنفيذ، للمستخدم، المجموعة، والآخرين.
    S_IRWXU S_IRUSR S_IWUSR S_IXUSR
    S_IRWXG S_IRGRP S_IWGRP S_IXGRP
    S_IRWXO S_IROTH S_IWOTH S_IXOTH
    # Setuid/Setgid/Stickiness/SaveText/EnforcedLocks.
    # لاحظ أن المعنى الدقيق لهذه يعتمد على النظام.
    S_ISUID S_ISGID S_ISVTX S_ISTXT S_ENFMT
    # أنواع الملفات. ليست كلها متوفرة بالضرورة على
    # نظامك.
    S_IFREG S_IFDIR S_IFLNK S_IFBLK S_IFCHR
    S_IFIFO S_IFSOCK S_IFWHT
    # فيما يلي أسماء مستعارة للتوافق مع S_IRUSR،
    # و S_IWUSR، و S_IXUSR.
    S_IREAD S_IWRITE S_IEXEC
    

ودوال "S_I*" هي

    S_IMODE($mode)    جزء $mode الذي يحتوي على بتات الأذونات
                      وبتات setuid/setgid/sticky
    S_IFMT($mode)     جزء $mode الذي يحتوي على نوع الملف،
                      والذي سيطابق أحد ثوابت S_IF*
                      (مثلاً S_IFMT($mode) == S_IFDIR للأدلة)،
                      لكن انظر الدوال المساعدة التالية
    # العوامل -f و -d و -l و -b و -c و -p و -S.
    S_ISREG($mode) S_ISDIR($mode) S_ISLNK($mode)
    S_ISBLK($mode) S_ISCHR($mode) S_ISFIFO($mode) S_ISSOCK($mode)
    # لا يوجد مقابل مباشر للعامل -X.
    S_ISWHT($mode)
    

راجع وثائق chmod(2) و stat(2) الأصلية لمزيد من التفاصيل حول ثوابت "S_I*". للحصول على معلومات الحالة لوصلة رمزية بدلاً من الملف الهدف وراء الوصلة، استخدم دالة "lstat".

قضايا المحمولية: "stat" في perlport.

تُصرح "state" عن متغير ذو نطاق معجمي، تماماً مثل "my". ومع ذلك، لن يتم إعادة تهيئة هذه المتغيرات أبداً، على عكس المتغيرات المعجمية التي تُعاد تهيئتها في كل مرة يتم فيها الدخول إلى الكتلة المحيطة بها. انظر "المتغيرات الخاصة المستمرة" في perlsub لمزيد من التفاصيل.

إذا تم سرد أكثر من متغير واحد، فيجب وضع القائمة بين قوسين. مع القائمة المقوسة، يمكن استخدام "undef" كمكان حجز وهمي. ومع ذلك، بما أن تهيئة متغيرات الحالة في مثل هذه القوائم غير ممكن حالياً، فلن يخدم هذا أي غرض.

مثل "my" و "local" و "our"، يمكن لـ "state" أن تعمل على متغير أينما ظهر في تعبير (باستثناء الإقحام في السلاسل النصية). لن ينطبق التصريح على الاستخدامات الإضافية لنفس المتغير حتى الجملة التالية. هذا يعني أن الاستخدامات الإضافية لذلك المتغير داخل نفس الجملة ستعمل كما كانت قبل حدوث ذلك التصريح، أو تؤدي إلى خطأ strict 'vars'، حسب الاقتضاء.

    package main;
    use feature 'state';
    our $x = 2;
    foo($x, state $x = $x + 1, $x); # تستقبل foo() قيم (2, 3, 2)
    foo($x, $main::x);              # تستقبل foo() قيم (3, 2)
    

إعادة التصريح عن متغير في نفس النطاق أو البيان سيؤدي إلى "حجب" (shadow) التصريح السابق، مما ينشئ نسخة جديدة ويمنع الوصول إلى النسخة السابقة. هذا عادة ما يكون غير مرغوب فيه، وإذا كانت التحذيرات مفعلة، فسيؤدي ذلك إلى تحذير في فئة "shadow".

تتوفر "state" فقط إذا مُكنت ميزة "state" أو إذا كانت مسبوقة بـ "CORE::". تُمكّن ميزة "state" آليًا مع إعلان "use v5.10" (أو أعلى) في النطاق الحالي.

study SCALAR
في هذا الوقت، لا تفعل "study" شيئاً. قد يتغير هذا في المستقبل.

قبل الإصدار 5.16 من Perl، كانت تقوم بإنشاء فهرس مقلوب لجميع المحارف التي ظهرت في SCALAR المعطى (أو $_ إذا لم يُحدد). عند مطابقة نمط، كان يتم البحث عن أندر محرف في النمط في هذا الفهرس. كانت الندرة تعتمد على بعض جداول التكرار الثابتة التي تم إنشاؤها من بعض برامج C والنصوص الإنجليزية.

هذا تعريف لروتين فرعي، وليس دالة حقيقية بحد ذاتها. بدون BLOCK فهو مجرد تصريح أمامي. وبدون NAME، فهو تصريح دالة مجهولة، لذا فإنه يعيد قيمة: مرجع CODE للـ closure الذي أُنشئ للتو.

انظر perlsub و perlref للحصول على تفاصيل حول الروتينات الفرعية والمراجع؛ انظر attributes و Attribute::Handlers لمزيد من المعلومات حول السمات.

__SUB__
وسم خاص يُرجع مرجعاً للروتين الفرعي الحالي، أو "undef" خارج الروتين الفرعي.

سلوك "__SUB__" داخل كتلة كود تعبير نمطي (مثل "/(?{...})/") عرضة للتغيير.

هذا الوسم متاح فقط تحت "use v5.16" أو ميزة "current_sub". انظر feature.

تستخرج سلسلة نصية فرعية من EXPR وتُرجعها. أول محرف يكون عند الإزاحة صفر. إذا كانت OFFSET سالبة، فإنها تبدأ من تلك المسافة من نهاية السلسلة. إذا تم حذف LENGTH، فإنها تُرجع كل شيء حتى نهاية السلسلة. إذا كانت LENGTH سالبة، فإنها تترك هذا العدد من المحارف في نهاية السلسلة.

    my $s = "The black cat climbed the green tree";
    my $color  = substr $s, 4, 5;      # black
    my $middle = substr $s, 4, -11;    # black cat climbed the
    my $end    = substr $s, 14;        # climbed the green tree
    my $tail   = substr $s, -4;        # tree
    my $z      = substr $s, -4, 2;     # tr
    

يمكنك استخدام دالة "substr" كقيمة يسارية (lvalue)، وفي هذه الحالة يجب أن تكون EXPR نفسها قيمة يسارية. إذا خصصت شيئاً أقصر من LENGTH، فستتقلص السلسلة، وإذا خصصت شيئاً أطول من LENGTH، فستنمو السلسلة لاستيعابه. للحفاظ على السلسلة بنفس الطول، قد تحتاج إلى حشو قيمتك أو تقطيعها باستخدام "sprintf".

إذا حدد OFFSET و LENGTH سلسلة فرعية تقع جزئياً خارج السلسلة النصية، فيُعاد الجزء الموجود داخل السلسلة فقط. إذا كانت السلسلة الفرعية وراء أي من طرفي السلسلة، فإن "substr" تعيد القيمة غير المعرفة وتصدر تحذيراً. عند استخدامها كقيمة يسارية (lvalue)، فإن تحديد سلسلة فرعية تقع بالكامل خارج السلسلة النصية يؤدي إلى إلقاء استثناء. فيما يلي مثال يوضح السلوك للحالات الحدية:

    my $name = 'fred';
    substr($name, 4) = 'dy';         # أصبح $name الآن 'freddy'
    my $null = substr $name, 6, 2;   # تُرجع "" (بدون تحذير)
    my $oops = substr $name, 7;      # تُرجع undef، مع تحذير
    substr($name, 7) = 'gap';        # تثير استثناءً
    

بديل لاستخدام "substr" كقيمة يسارية هو تحديد سلسلة REPLACEMENT كوسيط رابع. يتيح لك هذا استبدال أجزاء من EXPR وإرجاع ما كان موجوداً قبل ذلك في عملية واحدة، تماماً كما يمكنك مع "splice".

    my $s = "The black cat climbed the green tree";
    my $z = substr $s, 14, 7, "jumped from";    # climbed
    # $s أصبح الآن "The black cat jumped from the green tree"
    

لاحظ أن القيمة اليسارية (lvalue) التي يعيدها إصدار المعاملات الثلاثة من "substr" تعمل كـ 'رصاصة سحرية'؛ في كل مرة تُسند إليها قيمة، فإنها تتذكر أي جزء من السلسلة الأصلية يجري تعديله؛ على سبيل المثال:

    my $x = '1234';
    for (substr($x,1,2)) {
        $_ = 'a';   print $x,"\n";    # يطبع 1a4
        $_ = 'xyz'; print $x,"\n";    # يطبع 1xyz4
        $x = '56789';
        $_ = 'pq';  print $x,"\n";    # يطبع 5pq9
    }
    

مع الإزاحات السالبة، فإنها تتذكر موضعها من نهاية السلسلة عند تعديل السلسلة الهدف:

    my $x = '1234';
    for (substr($x, -3, 2)) {
        $_ = 'a';   print $x,"\n";    # يطبع 1a4، كما هو أعلاه
        $x = 'abcdefg';
        print $_,"\n";                # يطبع f
    }
    

قبل الإصدار 5.10 من Perl، كانت نتيجة استخدام القيمة اليسارية عدة مرات غير محددة. وقبل 5.16، كانت النتيجة مع الإزاحات السالبة غير محددة.

يُنشئ اسم ملف جديد مرتبطاً رمزياً باسم الملف القديم. يعيد 1 للنجاح، و 0 بخلاف ذلك. في الأنظمة التي لا تدعم الروابط الرمزية، يُلقى استثناء. للتحقق من ذلك، استخدم eval:

    my $symlink_exists = eval { symlink("",""); 1 };
    

مسائل قابلية النقل: "symlink" في perlport.

يستدعي استدعاء النظام المحدد كعنصر أول في القائمة، مع تمرير العناصر المتبقية كمعاملات لاستدعاء النظام. إذا لم يكن مُنفذاً، يُلقى استثناء. تُفسر المعاملات كما يلي: إذا كان المعامل المعطى عددياً، فيُمرر المعامل كعدد صحيح (int). وإذا لم يكن كذلك، فيُمرر المؤشر إلى قيمة السلسلة النصية. أنت مسؤول عن التأكد من أن السلسلة موسعة مسبقاً بما يكفي لاستقبال أي نتيجة قد تُكتب فيها. لا يمكنك استخدام سلسلة نصية صريحة (أو أي سلسلة نصية للقراءة فقط) كمعامل لـ "syscall" لأن Perl يجب أن تفترض أن أي مؤشر سلسلة قد يُكتب من خلاله. إذا لم تكن معاملات الأعداد الصحيحة صريحة ولم يسبق تفسيرها في سياق عددي، فقد تحتاج لإضافة 0 إليها لإجبارها على الظهور كأرقام. هذا يحاكي دالة "syswrite" (أو العكس):

    require 'syscall.ph';        # قد تحتاج لتشغيل h2ph
    my $s = "hi there\n";
    syscall(SYS_write(), fileno(STDOUT), $s, length $s);
    

لاحظ أن Perl تدعم تمرير ما يصل إلى 14 معاملًا فقط لنداء النظام الخاص بك، وهذا ما يكفي عادةً في الممارسة العملية.

تعيد Syscall أي قيمة يعيدها نداء النظام الذي تستدعيه. إذا فشل نداء النظام، تعيد "syscall" القيمة -1 وتضبط $! (errno). لاحظ أن بعض نداءات النظام يمكن أن تعيد القيمة -1 بشكل مشروع. الطريقة الصحيحة للتعامل مع مثل هذه النداءات هي تعيين "$! = 0" قبل النداء، ثم التحقق من قيمة $! إذا أعادت "syscall" القيمة -1.

هناك مشكلة في "syscall(SYS_pipe())": فهي تعيد رقم ملف طرف القراءة للأنبوب الذي تنشئه، ولكن لا توجد طريقة لاستعادة رقم ملف الطرف الآخر. يمكنك تجنب هذه المشكلة باستخدام "pipe" بدلاً من ذلك.

مسائل قابلية النقل: "syscall" في perlport.

يفتح الملف الذي يُعطى اسمه بواسطة FILENAME، ويربطه مع FILEHANDLE. إذا كان FILEHANDLE تعبيراً، فتُستخدم قيمته كمقبض ملف حقيقي مطلوب؛ وسيُحيى (autovivified) أي سلم غير معرف بشكل مناسب. تستدعي هذه الدالة وظيفة open(2) لنظام التشغيل الأساسي بالمعاملات FILENAME و MODE و PERMS.

تعيد صحيحًا عند النجاح و "undef" خلاف ذلك.

ستُطبق طبقات PerlIO على المقبض بنفس الطريقة التي تُطبق بها في نداء "open" الذي لا يحدد طبقات. أي، القيمة الحالية لـ "${^OPEN}" كما تم ضبطها بواسطة " "open pragma في نطاق لغوي، أو خيار سطر الأوامر "-C" أو متغير البيئة "PERL_UNICODE" في نطاق البرنامج الرئيس، مع الرجوع إلى القيم المبدئية للمنصة كما هو موضح في "Defaults and how to override them" في PerlIO. إذا كنت ترغب في إزالة أي طبقات قد تحول تدفق البايتات، فاستخدم "binmode" بعد فتحه.

القيم المحتملة وبتات الأعلام لمعامل MODE تعتمد على النظام؛ وهي متاحة عبر وحدة "Fcntl" القياسية. انظر وثائق استدعاء النظام open(2) لنظام التشغيل الخاص بك لمعرفة القيم وبتات الأعلام المتاحة. يمكنك دمج عدة أعلام باستخدام عامل "|".

من أكثر القيم شيوعًا "O_RDONLY" لفتح الملف في وضع القراءة فقط، و "O_WRONLY" لفتح الملف في وضع الكتابة فقط، و "O_RDWR" لفتح الملف في وضع القراءة والكتابة.

لأسباب تاريخية، تعمل بعض القيم على كل نظام تقريباً تدعمه Perl: الرقم 0 يعني للقراءة فقط، و1 يعني للكتابة فقط، و2 يعني للقراءة والكتابة. نحن نعلم أن هذه القيم لا تعمل تحت OS/390؛ ومن المحتمل أنك لا تريد استخدامها في كود جديد.

إذا كان الملف المسمى FILENAME غير موجود واستدعاء "open" يُنشئه (عادةً لأن MODE يتضمن علم "O_CREAT")، فإن قيمة PERMS تحدد أذونات الملف المنشأ حديثاً. إذا حذفت معامل PERMS في "sysopen"، تستخدم Perl القيمة الثمانية 0666. يجب أن تكون قيم الأذونات هذه بالنظام الثماني، وتُعدل بواسطة "umask" الحالية لعمليتك.

في العديد من الأنظمة، يتوفر علم "O_EXCL" لفتح الملفات في الوضع الحصري (exclusive). هذا ليس قفلاً: فالحصرية تعني هنا أنه إذا كان الملف موجوداً بالفعل، فإن "sysopen" تفشل. قد لا يعمل "O_EXCL" على أنظمة ملفات الشبكة، وليس له تأثير ما لم يتم ضبط علم "O_CREAT" أيضاً. يؤدي ضبط "O_CREAT|O_EXCL" إلى منع فتح الملف إذا كان رابطاً رمزياً. وهو لا يحمي من الروابط الرمزية في مسار الملف.

أحيانًا قد ترغب في تقليص ملف موجود بالفعل. يمكن القيام بذلك باستخدام علم "O_TRUNC". سلوك "O_TRUNC" مع "O_RDONLY" غير محدد.

يجب أن نادراً ما تستخدم 0644 كمعامل لـ "sysopen"، لأن ذلك يسلب المستخدم خيار الحصول على umask أكثر تسامحاً. من الأفضل حذفه. انظر "umask" لمزيد من المعلومات حول هذا الموضوع.

ليس لهذه الدالة علاقة مباشرة باستخدام "sysread" أو "syswrite" أو "sysseek". يمكن استخدام مقبض مفتوح بهذه الدالة مع الإدخال والإخراج المخبأ تمامًا كما يمكن استخدام مقبض مفتوح بـ "open" مع الإدخال والإخراج غير المخبأ.

لاحظ أنه في إصدارات Perl الأقدم من 5.8.0، تعتمد "sysopen" على وظيفة مكتبة C المسماة fdopen(3). في العديد من أنظمة Unix، من المعروف أن fdopen(3) تفشل عندما تتجاوز واصفات الملفات قيمة معينة، عادةً 255. إذا كنت بحاجة إلى واصفات ملفات أكثر من ذلك، ففكر في استخدام دالة "POSIX::open". بالنسبة لإصدارات Perl 5.8.0 وما بعدها، فإن PerlIO هي الخيار المبدئي (في أغلب الأحيان).

انظر perlopentut للحصول على شرح ألطف وأبسط لفتح الملفات.

مسائل قابلية النقل: "sysopen" في perlport.

تحاول قراءة LENGTH بايت من البيانات في المتغير SCALAR من مقبض الملف المحدد FILEHANDLE، باستخدام read(2). وهي تتجاوز أي طبقات PerlIO بما في ذلك الإدخال والإخراج المخبأ (لكنها تتأثر بوجود طبقة ":utf8" كما هو موضح لاحقًا)، لذا فإن خلط هذا مع أنواع أخرى من القراءات، أو "print" أو "write" أو "seek" أو "tell" أو "eof" يمكن أن يسبب ارتباكًا لأن طبقات ":perlio" أو ":crlf" تقوم عادةً بتخزين البيانات مؤقتًا. تعيد عدد البايتات التي تمت قراءتها بالفعل، أو 0 عند نهاية الملف، أو undef إذا كان هناك خطأ (في الحالة الأخيرة يتم ضبط $! أيضًا). سيتم تكبير أو تصغير SCALAR بحيث يكون آخر بايت تم قراءته فعليًا هو آخر بايت في المتغير القياسي بعد القراءة.

يمكن تحديد OFFSET لوضع البيانات المقروءة في مكان ما في السلسلة غير البداية. تحدد الإزاحة OFFSET السالبة الموضع بعدد من المحارف بالعد تنازلياً من نهاية السلسلة. أما الإزاحة OFFSET الموجبة الأكبر من طول SCALAR فتؤدي إلى حشو السلسلة إلى الحجم المطلوب ببايتات "\0" قبل إلحاق نتيجة القراءة.

    open(my $FH, "<", "input.txt") or die("تعذر فتح الملف: $!");
    my $buf = "";
    my $num = 0;
    # قراءة ما يصل إلى 64 بايت
    $num = sysread($FH, $buf, 64);
    # قراءة ما يصل إلى 32 بايت في الموضع 512 من $buf
    $num = sysread($FH, $buf, 32, 512);
    

لا توجد دالة syseof()، وهذا أمر جيد، بما أن "eof" لا تعمل جيداً على ملفات الأجهزة (مثل ttys) على أي حال. استخدم "sysread" وتحقق من قيمة العودة 0 لتحديد ما إذا كنت قد انتهيت.

لاحظ أنه إذا تم وسم مقبض الملف كـ ":utf8"، فإن "sysread" سترفع استثناءً. طبقة :encoding(...) تقدم ضمنيًا طبقة ":utf8". انظر "binmode" و "open" و open pragma.

يضبط موضع نظام FILEHANDLE بالبايت باستخدام lseek(2). قد يكون FILEHANDLE تعبيراً تعطي قيمته اسم مقبض الملف. قيم WHENCE هي 0 لضبط الموضع الجديد إلى POSITION؛ و 1 لضبطه على الموضع الحالي زائد POSITION؛ و 2 لضبطه على نهاية الملف (EOF) زائد POSITION، وعادة ما تكون القيمة سالبة.

لاحظ التأكيد على البايتات: حتى لو ضُبط مقبض الملف ليعمل على الأحرف (على سبيل المثال باستخدام طبقة الإدخال/الإخراج :encoding(UTF-8))، فإن عائلة الدوال "seek" و "tell" و "sysseek" تستخدم إزاحات البايت، وليس إزاحات الأحرف، لأن البحث إلى إزاحة أحرف سيكون بطيئاً جداً في ملف UTF-8.

تتجاوز "sysseek" الإدخال والإخراج المخبأ العادي، لذا فإن خلطها مع قراءات أخرى غير "sysread" (مثل "readline" أو "read")، أو "print" أو "write" أو "seek" أو "tell" أو "eof" قد يسبب ارتباكًا.

بالنسبة لـ WHENCE، يمكنك أيضًا استخدام الثوابت "SEEK_SET" و "SEEK_CUR" و "SEEK_END" (بداية الملف، الموضع الحالي، نهاية الملف) من وحدة Fcntl. استخدام الثوابت هو أيضًا أكثر قابلية للنقل من الاعتماد على 0 و 1 و 2. على سبيل المثال لتعريف دالة "systell":

    use Fcntl 'SEEK_CUR';
    sub systell { sysseek($_[0], 0, SEEK_CUR) }
    

تعيد الموضع الجديد، أو القيمة غير المعرفة عند الفشل. يتم إرجاع الموضع صفر كسلسلة نصية "0 but true"؛ وبالتالي فإن "sysseek" تعيد صحيحًا عند النجاح وخطأ عند الفشل، ومع ذلك لا يزال بإمكانك بسهولة تحديد الموضع الجديد.

تفعل تماماً نفس الشيء الذي تفعله "exec"، باستثناء أنه يتم إجراء تفريع (fork) أولاً وتنتظر العملية الأب خروج العملية الابن. لاحظ أن معالجة المعاملات تختلف اعتماداً على عدد المعاملات. إذا كان هناك أكثر من معامل واحد في LIST، أو إذا كانت LIST مصفوفة بأكثر من قيمة واحدة، فسيتم بدء البرنامج المعطى بواسطة العنصر الأول في القائمة بمعاملات معطاة بواسطة بقية القائمة. إذا كان هناك معامل سلمي واحد فقط، فيتم فحص المعامل بحثاً عن محارف الصدفة الخاصة (metacharacters)، وإذا وُجد أي منها، يُمرر المعامل بالكامل إلى صدفة أوامر النظام لتحليله (هذا هو "/bin/sh -c" على منصات يونكس، ولكنه يختلف على المنصات الأخرى). إذا لم تكن هناك محارف صدفة خاصة في المعامل، فيتم تقسيمه إلى كلمات وتمريره مباشرة إلى "execvp"، وهو أكثر كفاءة. على ويندوز، فقط صيغة "system PROGRAM LIST" ستتجنب استخدام الصدفة بشكل موثوق؛ أما "system LIST"، حتى مع أكثر من عنصر واحد، فستتراجع إلى الصدفة إذا فشلت عملية الإنشاء (spawn) الأولى.

ستحاول Perl تفريغ جميع الملفات المفتوحة للإخراج قبل أي عملية قد تقوم بـ fork، ولكن قد لا يكون هذا مدعومًا في بعض المنصات (راجع perlport). لتكون آمنًا، قد تحتاج إلى ضبط $| (أو $AUTOFLUSH بالإنجليزية) أو استدعاء تابع "autoflush" الخاص بـ "IO::Handle" على أي مقابض مفتوحة.

القيمة المعادة هي حالة خروج البرنامج كما أعادها استدعاء "wait". للحصول على قيمة الخروج الفعلية، قم بالإزاحة لليمين بمقدار ثمانية (انظر أدناه). انظر أيضاً "exec". هذا ليس ما تريد استخدامه لالتقاط المخرجات من أمر؛ لذلك يجب استخدام علامات الاقتباس المائلة (backticks) أو "qx//"، كما هو موضح في "`STRING`" في perlop. تشير القيمة المعادة -1 إلى الفشل في بدء البرنامج أو خطأ في استدعاء النظام wait(2) (افحص $! لمعرفة السبب).

إذا كنت ترغب في جعل "system" (وأجزاء أخرى كثيرة من Perl) تتوقف (die) عند حدوث خطأ، فراجع الموجه autodie.

مثل "exec"، تسمح لك "system" بالكذب على البرنامج بشأن اسمه إذا استخدمت صيغة "system PROGRAM LIST". مرة أخرى، انظر "exec".

بما أنه يتم تجاهل "SIGINT" و "SIGQUIT" أثناء تنفيذ "system"، فإذا كنت تتوقع أن ينتهي برنامجك عند تلقي هذه الإشارات، فستحتاج إلى ترتيب القيام بذلك بنفسك بناءً على القيمة المعادة.

    my @args = ("command", "arg1", "arg2");
    system(@args) == 0
        or die "system @args failed: $?";
    

إذا كنت ترغب في فحص فشل "system" يدوياً، يمكنك التحقق من جميع أوضاع الفشل الممكنة عن طريق فحص $? كالتالي:

    if ($? == -1) {
        print "failed to execute: $!\n";
    }
    elsif ($? & 127) {
        printf "child died with signal %d, %s coredump\n",
            ($? & 127),  ($? & 128) ? 'with' : 'without';
    }
    else {
        printf "child exited with value %d\n", $? >> 8;
    }
    

بدلاً من ذلك، يمكنك فحص قيمة "${^CHILD_ERROR_NATIVE}" باستخدام نداءات "W*()" من وحدة POSIX.

عندما تُنفذ معاملات "system" بشكل غير مباشر بواسطة الصدفة، فإن النتائج ورموز العودة تخضع لتقلباتها. انظر "`STRING`" في perlop و "exec" للحصول على التفاصيل.

بما أن "system" تقوم بـ "fork" و "wait" فقد تؤثر على معالج "SIGCHLD". انظر perlipc لمزيد من التفاصيل.

مسائل قابلية النقل: "system" في perlport.

تحاول كتابة LENGTH بايت من البيانات من المتغير SCALAR إلى مقبض الملف المحدد FILEHANDLE، باستخدام write(2). إذا لم يتم تحديد LENGTH، تكتب كامل SCALAR. تتجاوز أي طبقات PerlIO بما في ذلك الإدخال والإخراج المخبأ (لكنها تتأثر بوجود طبقة ":utf8" كما هو موضح لاحقًا)، لذا فإن خلطها مع عمليات القراءة (بخلاف "sysread)")، أو "print" أو "write" أو "seek" أو "tell" أو "eof" قد يسبب ارتباكًا لأن طبقات ":perlio" و ":crlf" تقوم عادةً بتخزين البيانات مؤقتًا. تعيد عدد البايتات التي كُتبت فعليًا، أو "undef" إذا كان هناك خطأ (في هذه الحالة يتم ضبط متغير errno $! أيضًا). إذا كان LENGTH أكبر من البيانات المتاحة في SCALAR بعد OFFSET، فسيتم كتابة البيانات المتاحة فقط.

يمكن تحديد OFFSET لكتابة البيانات من جزء معين من السلسلة النصية بدلاً من بدايتها. تحدد قيمة OFFSET السالبة الكتابة بعدد تلك الأحرف تنازليًا من نهاية السلسلة. إذا كان طول SCALAR صفرًا، فيمكنك فقط استخدام OFFSET بقيمة 0.

تحذير: إذا كان مقبض الملف موسومًا كـ ":utf8"، فإن "syswrite" سترفع استثناءً. تقدم طبقة :encoding(...) ضمنيًا طبقة ":utf8". بدلاً من ذلك، إذا لم يكن المقبض موسومًا بترميز ولكنك حاولت كتابة أحرف بنقاط كود تزيد عن 255، فسيتم رفع استثناء. انظر "binmode" و "open" و open pragma.

tell FILEHANDLE
تعيد الموضع الحالي بالبايتات لـ FILEHANDLE، أو -1 عند حدوث خطأ. قد يكون FILEHANDLE تعبيرًا تعطي قيمته اسم مقبض الملف الفعلي. إذا تم حذف FILEHANDLE، تفترض الملف الذي قُرئ آخراً.

لاحظ التأكيد على البايتات: حتى لو ضُبط مقبض الملف ليعمل على الأحرف (على سبيل المثال باستخدام طبقة الإدخال/الإخراج :encoding(UTF-8))، فإن عائلة الدوال "seek" و "tell" و "sysseek" تستخدم إزاحات البايت، وليس إزاحات الأحرف، لأن البحث إلى إزاحة أحرف سيكون بطيئاً جداً في ملف UTF-8.

تعتمد القيمة المعادة لـ "tell" للتدفقات القياسية مثل STDIN على نظام التشغيل: فقد تعيد -1 أو شيئًا آخر. وعادة ما تعيد "tell" على الأنابيب و fifos والمقابس القيمة -1.

لا توجد دالة "systell". استخدم "sysseek($fh, 0, 1)" لذلك.

لا تستخدم "tell" (أو غيرها من عمليات الإدخال/الإخراج المخبأة) على مقبض ملف تم التلاعب به بواسطة "sysread" أو "syswrite" أو "sysseek". تتجاهل تلك الدوال التخزين المؤقت، بينما لا تفعل "tell" ذلك.

تعيد الموضع الحالي لروتينات "readdir" على DIRHANDLE. يمكن إعطاء القيمة لـ "seekdir" للوصول إلى موقع معين في دليل. تخضع "telldir" لنفس المحاذير بشأن ضغط الدليل المحتمل مثل روتين مكتبة النظام المقابل.
تربط هذه الدالة متغيرًا بفئة حزمة ستوفر التنفيذ للمتغير. VARIABLE هو اسم المتغير المراد "سحره". CLASSNAME هو اسم الفئة التي تنفذ كائنات من النوع الصحيح. تُمرر أي معاملات إضافية إلى طريقة المنشئ المناسبة للفئة (بمعنى "TIESCALAR" أو "TIEHANDLE" أو "TIEARRAY" أو "TIEHASH"). وعادة ما تكون هذه المعاملات مثل تلك التي قد تُمرر إلى دالة dbm_open(3) في C. يتم أيضًا إرجاع الكائن الذي يرجعه المنشئ بواسطة دالة "tie"، وهو ما يكون مفيدًا إذا كنت تريد الوصول إلى طرق أخرى في CLASSNAME.

لاحظ أن دوالاً مثل "keys" و "values" قد تعيد قوائم ضخمة عند استخدامها على كائنات كبيرة، مثل ملفات DBM. قد تفضل استخدام دالة "each" للتكرار عبرها. مثال:

    # طباعة إزاحات ملف التاريخ
    use NDBM_File;
    tie(my %HIST, 'NDBM_File', '/usr/lib/news/history', 1, 0);
    while (my ($key,$val) = each %HIST) {
        print $key, ' = ', unpack('L', $val), "\n";
    }
    

يجب أن تحتوي الفئة التي تنفذ هاش (hash) على الطرق التالية:

    TIEHASH classname, LIST
    FETCH this, key
    STORE this, key, value
    DELETE this, key
    CLEAR this
    EXISTS this, key
    FIRSTKEY this
    NEXTKEY this, lastkey
    SCALAR this
    DESTROY this
    UNTIE this
    

يجب أن تحتوي الفئة التي تنفذ مصفوفة عادية على الطرق التالية:

    TIEARRAY classname, LIST
    FETCH this, key
    STORE this, key, value
    FETCHSIZE this
    STORESIZE this, count
    CLEAR this
    PUSH this, LIST
    POP this
    SHIFT this
    UNSHIFT this, LIST
    SPLICE this, offset, length, LIST
    EXTEND this, count
    DELETE this, key
    EXISTS this, key
    DESTROY this
    UNTIE this
    

يجب أن تحتوي الفئة التي تنفذ مقبض ملف على الطرق التالية:

    TIEHANDLE classname, LIST
    READ this, scalar, length, offset
    READLINE this
    GETC this
    WRITE this, scalar, length, offset
    PRINT this, LIST
    PRINTF this, format, LIST
    BINMODE this
    EOF this
    FILENO this
    SEEK this, position, whence
    TELL this
    OPEN this, mode, LIST
    CLOSE this
    DESTROY this
    UNTIE this
    

يجب أن تحتوي الفئة التي تنفذ متغيرًا قياسيًا على الطرق التالية:

    TIESCALAR classname, LIST
    FETCH this,
    STORE this, value
    DESTROY this
    UNTIE this
    

ليس بالضرورة تنفيذ جميع الطرق المذكورة أعلاه. انظر perltie و Tie::Hash و Tie::Array و Tie::Scalar و Tie::Handle.

على عكس "dbmopen"، فإن دالة "tie" لن تقوم بـ "use" أو "require" لوحدة برمجية نيابة عنك؛ تحتاج إلى القيام بذلك صراحة بنفسك. انظر DB_File أو وحدة Config للحصول على تنفيذات "tie" مثيرة للاهتمام.

لمزيد من التفاصيل انظر perltie و "tied".

تعيد مرجعاً للكائن الأساسي لـ VARIABLE (نفس القيمة التي أعيدت أصلاً بواسطة استدعاء "tie" الذي ربط المتغير بحزمة.) تعيد القيمة غير المعرفة إذا لم يكن VARIABLE مرتبطاً بحزمة.
تعيد عدد الثواني غير الكبيسة منذ الوقت الذي يعتبره النظام حقبة (epoch)، وهي مناسبة للتغذية لكل من "gmtime" و "localtime". في معظم الأنظمة، الحقبة هي 00:00:00 UTC، 1 يناير 1970؛ وهناك استثناء بارز وهو Mac OS Classic الذي يستخدم 00:00:00، 1 يناير 1904 في المنطقة الزمنية المحلية الحالية كحقبة له.

لقياس الوقت بدقة أفضل من ثانية واحدة، استخدم وحدة Time::HiRes بدءًا من Perl 5.8 فصاعدًا (أو من CPAN قبل ذلك)، أو، إذا كان لديك gettimeofday(2)، فقد تتمكن من استخدام واجهة "syscall" الخاصة بـ Perl. انظر perlfaq8 لمزيد من التفاصيل.

لمعالجة التاريخ والوقت، انظر إلى العديد من الوحدات ذات الصلة في CPAN. لتمثيل شامل للتاريخ والوقت، انظر إلى وحدة DateTime.

الأوقات
تعيد قائمة من أربعة عناصر تعطي أوقات المستخدم والنظام بالثواني لهذه العملية وأي عمليات أبناء منتهية لهذه العملية.

    my ($user,$system,$cuser,$csystem) = times;
    

في السياق القياسي، تعيد "times" القيمة $user.

تُضمّن أوقات العمليات الأبناء فقط للأبناء الذين تم إنهاؤهم.

مسائل قابلية النقل: "times" في perlport.

معامل حرفنة النصوص (transliteration). هو نفسه "y///". انظر "Quote-Like Operators" في perlop.
يقلص الملف المفتوح على FILEHANDLE، أو المسمى بواسطة EXPR، إلى الطول المحدد. يُلقى استثناء إذا لم تكن وظيفة truncate مُنفذة على نظامك. يعيد قيمة حقيقية عند النجاح، و "undef" عند حدوث خطأ.

السلوك غير محدد إذا كان LENGTH أكبر من طول الملف.

يُترك موضع FILEHANDLE في الملف دون تغيير. قد ترغب في استدعاء seek قبل الكتابة في الملف.

مسائل قابلية النقل: "truncate" في perlport.

uc EXPR
تعيد نسخة من EXPR بأحرف كبيرة. إذا تم حذف EXPR، تستخدم $_.

    my $str = uc("Perl is GREAT"); # "PERL IS GREAT"
    

تتصرف هذه الدالة بالطريقة نفسها التي تتصرف بها "lc" تحت مختلف البرغما (pragmas)، كما هو الحال في المحلية.

إذا كنت تريد تحويل الحروف الأولى فقط لأحرف كبيرة (titlecase)، فراجع "ucfirst" بدلاً من ذلك.

ملاحظة: هذه هي الدالة الداخلية التي تنفذ محرف الهروب "\U" في السلاسل النصية ذات الاقتباس المزدوج.

    my $str = "Perl is \Ugreat\E"; # "Perl is GREAT"
    
ucfirst EXPR
تعيد قيمة EXPR مع تحويل الحرف الأول إلى حرف كبير (يسمي يونيكود هذا titlecase). إذا تم حذف EXPR، تستخدم "ucfirst" المتغير $_.

    my $str = ucfirst("hello world!"); # "Hello world!"
    

تتصرف هذه الدالة بالطريقة نفسها التي تتصرف بها "lc" تحت مختلف البرغما (pragmas)، كما هو الحال في المحلية.

ملاحظة: هذه هي الدالة الداخلية التي تنفذ محرف الهروب "\u" في السلاسل النصية ذات الاقتباس المزدوج.

    my $str = "\uperl\E is great"; # "Perl is great"
    
umask EXPR
تضبط umask للعملية على EXPR وتعيد القيمة السابقة. إذا تم حذف EXPR، تعيد umask الحالية فحسب.

تُمثل أذونات يونكس "rwxr-x---" كبثلاث مجموعات من ثلاث بتات، أو ثلاث أرقام ثمانية: 0750 (الصفر البادئ يشير إلى النظام الثماني وليس أحد الأرقام). قيمة "umask" هي رقم يمثل بتات الأذونات المعطلة. قيم الأذونات (أو "الوضع" (mode)) التي تمررها لـ "mkdir" أو "sysopen" تُعدل بواسطة umask الخاص بك، لذا حتى لو أخبرت "sysopen" بإنشاء ملف بأذونات 0777، وكان umask الخاص بك هو 0022، فسيتم إنشاء الملف فعلياً بأذونات 0755. إذا كان "umask" الخاص بك هو 0027 (لا يمكن للمجموعة الكتابة؛ ولا يمكن للآخرين القراءة أو الكتابة أو التنفيذ)، فإن تمرير "sysopen" القيمة 0666 سيؤدي لإنشاء ملف بالوضع 0640 (لأن "0666 &~ 027" هو 0640).

إليك بعض النصائح: قدم وضع إنشاء بقيمة 0666 للملفات العادية (في "sysopen") ووضع بقيمة 0777 للأدلة (في "mkdir") والملفات التنفيذية. وهذا يعطي المستخدمين حرية الاختيار: إذا أرادوا ملفات محمية، فقد يختارون umask للعملية بقيمة 022، أو 027، أو حتى القناع غير الاجتماعي للغاية بقيمة 077. يجب أن نادراً ما تتخذ البرامج قرارات سياسية من الأفضل تركها للمستخدم. والاستثناء من ذلك هو عند كتابة ملفات يجب أن تظل خاصة: ملفات البريد، ملفات تعريف ارتباط متصفح الويب، ملفات .rhosts، وما إلى ذلك.

إذا كان umask(2) غير منفذ في نظامك وكنت تحاول تقييد الوصول لنفسك (أي، "(EXPR & 0700) > 0")، يتم رفع استثناء. إذا كان umask(2) غير منفذ ولم تكن تحاول تقييد الوصول لنفسك، تعيد "undef".

تذكر أن umask هو رقم، وعادة ما يُعطى بالنظام الثماني؛ وليس سلسلة من الأرقام الثمانية. انظر أيضًا "oct"، إذا كان كل ما تملكه هو سلسلة نصية.

مسائل قابلية النقل: "umask" في perlport.

undef EXPR
تلغي تعريف قيمة EXPR، والتي يجب أن تكون قيمة يسارية (lvalue). استخدمها فقط على قيمة سلمية، أو مصفوفة (باستخدام "@")، أو هش (باستخدام "%")، أو روتين فرعي (باستخدام "&")، أو typeglob (باستخدام "*"). من المحتمل ألا يؤدي قول "undef $hash{$key}" إلى ما تتوقعه على معظم المتغيرات المحددة مسبقاً أو قيم قائمة DBM، لذا لا تفعل ذلك؛ انظر "delete". تعيد دائماً القيمة غير المعرفة. يمكنك حذف EXPR، وفي هذه الحالة لا يتم إلغاء تعريف أي شيء، ولكنك لا تزال تحصل على قيمة غير معرفة يمكنك، على سبيل المثال، إعادتها من روتين فرعي، أو إسنادها لمتغير، أو تمريرها كمعامل. أمثلة:

    undef $foo;
    undef $bar{'blurfl'};      # قارن مع: delete $bar{'blurfl'};
    undef @ary;
    undef %hash;
    undef &mysub;
    undef *xyz;       # يدمر $xyz و @xyz و %xyz و &xyz... إلخ.
    return (wantarray ? (undef, $errmsg) : undef) if $they_blew_it;
    select undef, undef, undef, 0.25;
    my ($x, $y, undef, $z) = foo();    # تجاهل القيمة الثالثة المعادة
    

لاحظ أن هذا معامل أحادي، وليس معامل قائمة.

unlink LIST
تحذف قائمة من الملفات. عند النجاح، تعيد عدد الملفات التي حذفتها بنجاح. وعند الفشل، تعيد خطأ وتضبط $! (errno):

    my $unlinked = unlink 'a', 'b', 'c';
    unlink @goners;
    unlink glob "*.bak";
    

عند حدوث خطأ، لن تخبرك "unlink" بالملفات التي لم تتمكن من إزالتها. إذا كنت تريد معرفة الملفات التي لم تستطع إزالتها، فجربها واحدًا تلو الآخر:

     foreach my $file ( @goners ) {
         unlink $file or warn "Could not unlink $file: $!";
     }
    

ملاحظة: لن تحاول "unlink" حذف الأدلة ما لم تكن مستخدمًا متميزًا (superuser) وتم توفير العلم -U لـ Perl. حتى لو تم استيفاء هذه الشروط، فاحذر من أن فك ارتباط الدليل يمكن أن يلحق الضرر بنظام الملفات الخاص بك. أخيرًا، استخدام "unlink" على الأدلة غير مدعوم في العديد من أنظمة التشغيل. استخدم "rmdir" بدلاً من ذلك.

إذا أُسقطت القائمة LIST، تستخدم "unlink" المتغير $_.

تقوم "unpack" بعكس ما تفعله "pack": فهي تأخذ سلسلة نصية وتوسعها إلى قائمة من القيم. (في سياق عددي، تُرجع القيمة الأولى الناتجة فقط.)

إذا أُسقط التعبير EXPR، تُفك السلسلة النصية $_. انظر perlpacktut للحصول على مقدمة عن هذه الدالة.

تُجزأ السلسلة النصية إلى مقاطع يصفها القالب TEMPLATE. يُحول كل مقطع بشكل منفصل إلى قيمة. عادةً ما تكون السلسلة إما نتيجة لـ "pack"، أو تمثل محارف السلسلة بنية C من نوع ما.

تملك TEMPLATE نفس التنسيق الموجود في دالة "pack". فيما يلي روتين فرعي يقوم بعمل سلسلة فرعية:

    sub substr {
        my ($what, $where, $howmuch) = @_;
        unpack("x$where a$howmuch", $what);
    }
    

ثم هناك

    sub ordinal { unpack("W",$_[0]); } # مثل ()ord تماماً
    

بالإضافة إلى الحقول المسموح بها في "pack"، يمكنك بدء الحقل بـ %<number> للإشارة إلى أنك تريد مجموعاً تدقيقياً (checksum) بطول <number> بت للعناصر بدلاً من العناصر نفسها. القيمة المبدئية هي مجموع تدقيقي بطول 16 بت. يُحسب المجموع التدقيقي بجمع القيم الرقمية للقيم الموسعة (في حقول السلاسل النصية يُجمع ord($char)؛ وفي حقول البتات يُجمع الصفر والواحد).

على سبيل المثال، يحسب الكود التالي الرقم نفسه الذي يحسبه برنامج sum في System V:

    my $checksum = do {
        local $/;  # قراءة الملف بالكامل!
        unpack("%32W*", readline) % 65535;
    };
    

يقوم الكود التالي بعدّ البتات المُعدة (set bits) في متجّه بتات بكفاءة:

    my $setbits = unpack("%32b*", $selectmask);
    

يجب استخدام تنسيقات "p" و "P" بحذر. بما أنه لا توجد طريقة لـ Perl للتحقق مما إذا كانت القيمة الممررة إلى "unpack" تتوافق مع موقع ذاكرة صالح، فإن تمرير قيمة مؤشر غير معروف بصلاحيتها من المرجح أن يؤدي لعواقب وخيمة.

إذا كان هناك المزيد من رموز الحزم أو إذا كان عدد مرات التكرار لحقل أو مجموعة أكبر مما تسمح به بقية سلسلة الإدخال، فإن النتيجة غير محددة جيداً: قد يُقلل عدد مرات التكرار، أو قد تُنتج "unpack" سلاسل فارغة أو أصفاراً، أو قد تثير استثناءً. إذا كانت سلسلة الإدخال أطول مما يصفه القالب TEMPLATE، فتُتجاهل بقية سلسلة الإدخال تلك.

انظر "pack" لمزيد من الأمثلة والملاحظات.

يضيف عنصراً واحداً أو أكثر إلى بداية المصفوفة. وهذا عكس عملية "shift".

    my @animals = ("cat");
    unshift(@animals, "mouse"); # ("mouse", "cat")
    my @colors = ("red");
    unshift(@colors, ("blue", "green")); # ("blue", "green", "red")
    

تُرجع العدد الجديد للعناصر في المصفوفة المحدثة.

    # القيمة المرجعة هي عدد العناصر في المصفوفة المحدثة
    my $color_count = unshift(@colors, ("yellow", "purple"));
    say "There are $color_count colors in the updated array";
    

لاحظ أن القائمة LIST تُضاف في البداية ككتلة واحدة، وليس عنصراً تلو الآخر، لذا تبقى العناصر المضافة بالترتيب نفسه. استخدم "reverse" للقيام بالعكس.

بدءاً من إصدار بيرل 5.14، سمحت ميزة تجريبية لـ "unshift" بأخذ تعبير عددي. اعتُبرت هذه التجربة غير ناجحة، وأُزيلت اعتباراً من بيرل 5.24.

يفك الارتباط بين متغير وحزمة ما. (انظر tie.) ليس له أي تأثير إذا لم يكن المتغير مرتبطاً (tied).
يستورد بعض الدلالات (semantics) إلى الحزمة الحالية من الوحدة المسماة، عادةً عن طريق تعيين أسماء مستعارة لروتينات فرعية أو متغيرات معينة في حزمتك. إنه يعادل تماماً

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

إلا أن Module يجب أن يكون كلمة صريحة (bareword). يمكن جعل الاستيراد مشروطاً باستخدام وحدة if.

تُجبر "BEGIN" كلاً من "require" و "import" على الحدوث في وقت التصريف. وتتأكد "require" من تحميل الوحدة النمطية في الذاكرة إذا لم تكن قد حُمّلت بعد. و "import" ليست دالة مضمنة؛ بل هي مجرد استدعاء تابع ثابت عادي في حزمة "Module" لإخبار الوحدة باستيراد قائمة الميزات مرة أخرى إلى الحزمة الحالية. يمكن للوحدة تنفيذ تابع "import" الخاص بها بأي طريقة تريدها، على الرغم من أن معظم الوحدات تختار فقط اشتقاق تابع "import" الخاص بها عبر الوراثة من فئة "Exporter" المعرفة في وحدة "Exporter". انظر Exporter. إذا لم يتم العثور على تابع "import"، فسيتم تخطي الاستدعاء، حتى لو كان هناك تابع AUTOLOAD.

إذا كنت لا تريد استدعاء تابع "import" للحزمة (على سبيل المثال، لمنع تعديل فضاء التسمية الخاص بك)، فقدم صراحةً القائمة الفارغة:

    use Module ();
    

وهذا يعادل تماماً

    BEGIN { require Module }
    

إذا كانت وسيطة الإصدار VERSION موجودة بين Module و LIST، فإن "use" ستستدعي أسلوب "VERSION" في فئة Module مع الإصدار المعطى كوسيطة:

    use Module 12.34;
    

يعادل:

    BEGIN { require Module; Module->VERSION(12.34) }
    

أسلوب "VERSION" المبدئي، الموروث من فئة "UNIVERSAL"، يُصدر خطأ (croaks) إذا كان الإصدار المعطى أكبر من قيمة المتغير $Module::VERSION.

لا يمكن أن يكون معامل VERSION تعبيراً عشوائياً. يُحتسب فقط كمعامل VERSION إذا كان صريحاً لرقم إصدار، يبدأ إما برقم أو بـ "v" متبوعاً برقم. وأي شيء لا يبدو كقيمة إصدار صريحة سيُحلل كبداية لـ LIST. ومع ذلك، فإن العديد من المحاولات لاستخدام تعبير عشوائي كمعامل VERSION ستظهر وكأنها تعمل، لأن تابع "import" الخاص بـ Exporter يعالج المعاملات الرقمية بشكل خاص، حيث يقوم بفحوصات الإصدار بدلاً من معاملتها كأشياء للتصدير.

مرة أخرى، هناك فرق بين إسقاط LIST (استدعاء "import" بدون وسائط) وبين قائمة فارغة صريحة "()" (عدم استدعاء "import"). لاحظ أنه لا توجد فاصلة بعد VERSION!

بما أن هذه واجهة مفتوحة تماماً، فإن تعليمات المصرّف (pragmas) تُنَفذ أيضاً بهذه الطريقة. بعض التعليمات المنفذة حالياً هي:

    use constant;
    use diagnostics;
    use integer;
    use feature  qw(say signatures bitwise);
    use sigtrap  qw(SEGV BUS);
    use strict   qw(subs vars refs);
    use subs     qw(afunc blurfl);
    use warnings qw(all);
    

تستورد بعض هذه الوحدات الوهمية دلالات في نطاق الكتلة الحالي (مثل "strict" أو "integer")، على عكس الوحدات العادية التي تستورد الرموز إلى الحزمة الحالية (والتي تظل فعالة حتى نهاية الملف).

لأن "use" يسري مفعولها في وقت التصريف، فهي لا تحترم تدفق التحكم العادي للكود الجاري تصريفه. وبوجه الخصوص، فإن وضع "use" داخل الفرع الخاطئ لشرط لا يمنع معالجتها. إذا كانت الوحدة النمطية أو الموجه يحتاج فقط للتحميل بشكل مشروط، فيمكن القيام بذلك باستخدام موجه if:

    use if $] < 5.008, "utf8";
    use if WANT_WARNINGS, warnings => qw(all);
    

هناك تصريح "no" المقابل الذي يلغي استيراد المعاني المستوردة بواسطة "use"، أي أنه يستدعي "Module->unimport(LIST)" بدلاً من "import". وهو يتصرف تماماً كما تفعل "import" مع VERSION، أو LIST محذوفة أو فارغة، أو عدم العثور على تابع unimport.

    no integer;
    no strict 'refs';
    no warnings;
    

انظر perlmodlib للحصول على قائمة بالوحدات والتعليمات القياسية. انظر perlrun لخيارات سطر الأوامر "-M" و "-m" لبيرل التي تمنح وظائف "use" من سطر الأوامر.

تمكن معجمياً جميع الميزات المتاحة في الإصدار المطلوب كما هو محدد بواسطة موجه feature، مع تعطيل أي ميزات ليست في حزمة ميزات الإصدار المطلوب. انظر feature.

قد يكون VERSION إما سلسلة-v مثل v5.24.1، والتي ستُقارن بـ $^V (المعروف أيضاً بـ $PERL_VERSION)، أو وسيطة رقمية بتنسيق 5.024001، والتي ستُقارن بـ $]. يُثار استثناء إذا كان VERSION أكبر من إصدار مفسر بيرل الحالي؛ ولن يحاول بيرل تحليل بقية الملف. قارن هذا مع "require"، التي يمكنها إجراء فحص مماثل في وقت التشغيل.

إذا كان إصدار بيرل المحدد 5.12 أو أعلى، تُفعل الضوابط (strictures) معجمياً كما هو الحال مع "use strict".

إذا كان إصدار بيرل المحدد 5.35.0 أو أعلى، تُفعل التحذيرات (warnings).

إذا كان إصدار بيرل المحدد 5.39.0 أو أعلى، تُستورد الدوال المدمجة معجمياً كما هو الحال مع "use builtin" مع حزمة إصدار مقابلة.

لا يُسمح باستخدام "use VERSION" بينما يوجد آخر ساري المفعول مع إصدار "use v5.39;" أو أعلى. بالنسبة للإصدارات الأقل، سوف تتجاوز "use VERSION" معظم سلوك "use VERSION" السابق، وربما تزيل آثار "warnings" و "feature" التي أضيفت بواسطته. هذا السلوك مهجور، وسيمنع إصدار مستقبلي من بيرل تغيير الإصدار بمجرد الإعلان عنه. بالإضافة إلى ذلك، لا يُسمح بـ "use VERSION" بإصدار أقل من 5.11 بعد "use VERSION" بإصدار أكبر من 5.11.

لا تقوم "use VERSION" بتحميل ملفات feature.pm أو strict.pm أو warnings.pm أو builtin.pm، بل تنفذ الوظائف المعادلة مباشرة.

في التنفيذ الحالي، أي استخدام صريح لـ "no strict" يتجاوز "use VERSION"، حتى لو جاء قبله. ومع ذلك، قد يخضع هذا للتغيير في إصدار مستقبلي من بيرل، لذا لا ينبغي للكود الجديد الاعتماد على هذه الحقيقة. يُوصى بأن يكون إعلان "use VERSION" هو أول تعبير مهم داخل الملف (ربما بعد تعبير "package" أو أي قدر من الفراغات أو التعليقات)، بحيث تظهر آثاره أولاً، وتطبق التعليمات الأخرى بعده.

ينبغي تجنب تحديد VERSION كوسيطة رقمية بتنسيق 5.024001 بشكل عام، لأنها صياغة قديمة وأقل قابلية للقراءة مقارنة بـ v5.24.1. قبل إصدار بيرل 5.8.0 في عام 2002، كانت الصيغة الرقمية الأكثر تفصيلاً هي الصياغة الوحيدة المدعومة، ولهذا السبب قد تراها في الأكواد القديمة.

    use v5.24.1;    # فحص الإصدار وقت التصريف
    use 5.24.1;     # مثله
    use 5.024_001;  # مثله؛ صياغة قديمة متوافقة مع بيرل 5.6
    

غالباً ما يكون هذا مفيداً إذا كنت بحاجة للتحقق من إصدار Perl الحالي قبل استخدام "use" لوحدات مكتبة لن تعمل مع الإصدارات الأقدم من Perl. (نحاول عدم فعل ذلك أكثر مما يجب.)

بشكل متماثل، تسمح لك "no VERSION" بتحديد أنك تريد إصداراً من بيرل أقدم من الإصدار المحدد. تاريخياً، أضيفت هذه الميزة أثناء التصميمات المبكرة للغة راكو (المعروفة سابقاً بـ "بيرل 6")، بحيث يمكن لبرنامج بيرل 5 أن يبدأ بـ

    no 6;
    

للإعلان عن أنه ليس برنامج بيرل 6. وبما أن اللغتين لهما تنفيذات مختلفة، واصطلاحات تسمية ملفات، وبنية تحتية أخرى، فإن هذه الميزة قليلة الاستخدام الآن في الممارسة العملية وينبغي تجنبها في الكود المكتوب حديثاً.

يجب توخي الحذر عند استخدام صيغة "no VERSION"، حيث إنها مخصصة فقط للتأكيد على أن نسخة Perl قيد التشغيل هي إصدار أقدم من معاملها وليس لإلغاء التأثيرات الجانبية لتمكين الميزات الخاصة بـ "use VERSION".

يغير وقت الوصول ووقت التعديل لكل ملف في قائمة الملفات. يجب أن يكون أول عنصرين في القائمة هما أوقات الوصول والتعديل الرقمية، بهذا الترتيب. تُرجع عدد الملفات التي غُيرت بنجاح. يُضبط وقت تغيير inode لكل ملف على الوقت الحالي. على سبيل المثال، هذا الكود له مفعول أمر touch(1) في يونكس نفسه عندما تكون الملفات موجودة بالفعل وتخص المستخدم الذي يقوم بتشغيل البرنامج:

    #!/usr/bin/perl
    my $atime = my $mtime = time;
    utime $atime, $mtime, @ARGV;
    

منذ إصدار Perl 5.8.0، إذا كان أول عنصرين من القائمة هما "undef"، فسيُستدعى استدعاء النظام utime(2) من مكتبة C الخاصة بك بمعامل ثانٍ فارغ (null). في معظم الأنظمة، سيؤدي هذا لضبط أوقات الوصول والتعديل للملف على الوقت الحالي (أي ما يعادل المثال أعلاه) وسيعمل حتى على الملفات التي لا تملكها بشرط توفر إذن الكتابة:

    for my $file (@ARGV) {
        utime(undef, undef, $file)
            || warn "تعذر لمس $file: $!";
    }
    

تحت نظام NFS سيُستخدم وقت خادم NFS، وليس وقت الجهاز المحلي. إذا كانت هناك مشكلة في مزامنة الوقت، فسيكون لخادم NFS والجهاز المحلي أوقات مختلفة. في الواقع، يستخدم أمر touch(1) في يونكس عادةً هذه الصيغة بدلاً من الصيغة الموضحة في المثال الأول.

تمرير واحد فقط من العنصرين الأولين كـ "undef" يعادل تمرير 0 ولن يكون له التأثير الموصوف عندما يكون كلاهما "undef". يؤدي هذا أيضاً إلى إطلاق تحذير بشأن عدم التهيئة.

في الأنظمة التي تدعم futimes(2)، يمكنك تمرير مقابض الملفات بين الملفات. في الأنظمة التي لا تدعم futimes(2)، فإن تمرير مقابض الملفات يؤدي لإلقاء استثناء. يجب تمرير مقابض الملفات كـ globs أو مراجع glob ليتم التعرف عليها؛ أما الكلمات المجردة (barewords) فتُعتبر أسماء ملفات.

قضايا القابلية للنقل: "utime" في perlport.

عند استدعائها في سياق قائمة، تعيد قائمة تتكون من جميع قيم الهش المسمى، أو في إصدار Perl 5.12 أو أحدث، قيم مصفوفة. إصدارات Perl قبل 5.12 ستنتج خطأ في بناء الجملة إذا حاولت استخدام معامل مصفوفة. في سياق سلمي، تعيد عدد المفاتيح أو الفهارس.

تُعاد مدخلات المصفوفة بترتيب الفهرس الأدنى أولاً.

تُعاد مدخلات الهش بترتيب عشوائي ظاهرياً. الترتيب العشوائي الفعلي خاص بهش معين؛ نفس السلسلة من العمليات بالضبط على اثنان من الهش قد تؤدي لترتيب مختلف لكل منهما. أي عملية إدراج في الهش قد تغير الترتيب، وكذلك أي عملية حذف، باستثناء أن أحدث مفتاح أعادته "each" أو "keys" يمكن حذفه دون تغيير الترتيب. طالما أن الهش المعطى لم يُعدل يمكنك الاعتماد على "keys" و "values" و "each" لإعادة نفس الترتيب مراراً وتكراراً. انظر "Algorithmic Complexity Attacks" في perlsec للحصول على تفاصيل حول سبب عشوائية ترتيب الهش. بعيداً عن الضمانات المقدمة هنا، فإن التفاصيل الدقيقة لخوارزمية الهش في Perl وترتيب تجاوز الهش عرضة للتغيير في أي إصدار من Perl. الهش المرتبط (Tied hashes) قد يتصرف بشكل مختلف عن هش Perl فيما يتعلق بتغيير الترتيب عند إدراج وحذف العناصر.

كأثر جانبي، يؤدي استدعاء "values" إلى إعادة تعيين المكرر (iterator) الداخلي لـ HASH أو ARRAY (انظر "each") قبل إخراج القيم. وبوجه خاص، فإن استدعاء "values" في سياق فارغ (void context) يعيد تعيين المكرر دون أي عبء إضافي.

بصرف النظر عن إعادة ضبط المكرر، فإن "values @array" في سياق قائمة هي نفسها @array العادية. (نوصي باستخدام "keys @array" في سياق فارغ لهذا الغرض، ولكننا ارتأينا أن إزالة "values @array" ستتطلب توثيقاً أكثر من تركها.)

لاحظ أن القيم لا تُنسخ، مما يعني أن تعديلها سيعدل محتويات الهاش:

    for (values %hash)      { s/foo/bar/g }  # يعدل قيم hash%
    for (@hash{keys %hash}) { s/foo/bar/g }  # نفسه
    

بدءاً من إصدار بيرل 5.14، سمحت ميزة تجريبية لـ "values" بأخذ تعبير عددي. اعتُبرت هذه التجربة غير ناجحة، وأُزيلت اعتباراً من بيرل 5.24.

لتجنب إرباك المستخدمين المحتملين لكودك الذين يشغلون إصدارات أقدم من Perl بأخطاء صياغة غامضة، ضع هذا النوع من الأشياء في أعلى ملفك للإشارة إلى أن كودك سيعمل فقط على إصدارات Perl الحديثة:

    use v5.12;  # لكي تعمل keys/values/each على المصفوفات
    

انظر أيضًا "keys" و "each" و "sort".

يعامل السلسلة النصية في EXPR كمتجه بتات مكون من عناصر بعرض BITS ويعيد قيمة العنصر المحدد بواسطة OFFSET كعدد صحيح بدون إشارة. وبالتالي يحدد BITS عدد البتات المحجوزة لكل عنصر في متجه البتات. يجب أن يكون هذا الرقم قوة للعدد اثنين من 1 إلى 32 (أو 64، إذا كانت منصتك تدعم ذلك).

إذا كان BITS هو 8، فإن "العناصر" تتطابق مع بايتات سلسلة المدخلات.

إذا كان BITS هو 16 أو أكثر، يتم تجميع بايتات سلسلة المدخلات في كتل بحجم BITS/8، وتُحول كل مجموعة إلى رقم كما هو الحال مع "pack"/"unpack" بتنسيقات النهاية الكبرى (big-endian) "n"/"N" (وبالمثل لـ BITS==64). راجع "pack" للتفاصيل.

إذا كان عدد البتات 4 أو أقل، يتم تقسيم السلسلة إلى بايتات، ثم يتم تقسيم بتات كل بايت إلى 8/BITS من المجموعات. تُرقم بتات البايت بطريقة تشبه النهاية الصغرى (little-endian)، كما في 0x01، 0x02، 0x04، 0x08، 0x10، 0x20، 0x40، 0x80. على سبيل المثال، تقسيم بايت المدخلات المنفرد chr(0x36) إلى مجموعتين يعطي القائمة "(0x6, 0x3)"؛ وتقسيمه إلى 4 مجموعات يعطي "(0x2, 0x1, 0x3, 0x0)".

يمكن أيضًا التعيين إلى "vec"، وفي هذه الحالة يلزم استخدام الأقواس لمنح التعبير الأسبقية الصحيحة كما في

    vec($image, $max_x * $x + $y, 8) = 3;
    

إذا كان العنصر المحدد خارج السلسلة، يتم إرجاع القيمة 0. إذا تمت الكتابة إلى عنصر يتجاوز نهاية السلسلة، سيقوم Perl أولاً بتوسيع السلسلة بعدد كافٍ من بايتات الصفر. من الخطأ محاولة الكتابة قبل بداية السلسلة (أي OFFSET سالب).

إذا صدف أن السلسلة قد رُمّزت بتنسيق UTF-8 داخليًا (وبالتالي لُصق لها وسم UTF8)، فإن "vec" يحاول تحويلها لاستخدام تمثيل داخلي بمقدار بايت واحد لكل محرف. ومع ذلك، إذا احتوت السلسلة على محارف بقيم 256 أو أعلى، سيحدث خطأ فادح.

يمكن أيضًا معالجة السلاسل المنشأة بواسطة "vec" باستخدام العوامل المنطقية "|" و "&" و "^" و "~". ستفترض هذه العوامل أن المطلوب هو عملية متجهة بتات عندما يكون كلا المعاملين سلسلتين. راجع "Bitwise String Operators" في perlop.

سيبني الكود التالي سلسلة ASCII نصها 'PerlPerlPerl'. تُظهر التعليقات السلسلة بعد كل خطوة. لاحظ أن هذا الكود يعمل بنفس الطريقة على الحواسيب ذات الترتيب الصغير أو الكبير للبايتات.

    my $foo = '';
    vec($foo,  0, 32) = 0x5065726C; # 'Perl'
    # $foo eq "Perl" eq "\x50\x65\x72\x6C", 32 bits
    print vec($foo, 0, 8);  # prints 80 == 0x50 == ord('P')
    vec($foo,  2, 16) = 0x5065; # 'PerlPe'
    vec($foo,  3, 16) = 0x726C; # 'PerlPerl'
    vec($foo,  8,  8) = 0x50;   # 'PerlPerlP'
    vec($foo,  9,  8) = 0x65;   # 'PerlPerlPe'
    vec($foo, 20,  4) = 2;      # 'PerlPerlPe'   . "\x02"
    vec($foo, 21,  4) = 7;      # 'PerlPerlPer'
                                   # 'r' is "\x72"
    vec($foo, 45,  2) = 3;      # 'PerlPerlPer'  . "\x0c"
    vec($foo, 93,  1) = 1;      # 'PerlPerlPer'  . "\x2c"
    vec($foo, 94,  1) = 1;      # 'PerlPerlPerl'
                                   # 'l' is "\x6c"
    

لتحويل متجه بتات إلى سلسلة نصية أو قائمة من الأصفار والآحاد، استخدم هذه:

    my $bits = unpack("b*", $vector);
    my @bits = split(//, unpack("b*", $vector));
    

إذا علمت الطول الدقيق بالبتات، فيمكن استخدامه بدلاً من "*".

إليك مثال لتوضيح كيفية وقوع البتات في مكانها فعليًا:

  #!/usr/bin/perl -wl
  print <<'EOT';
                                    0         1         2         3
                     unpack("V",$_) 01234567890123456789012345678901
  ------------------------------------------------------------------
  EOT
  for $w (0..3) {
      $width = 2**$w;
      for ($shift=0; $shift < $width; ++$shift) {
          for ($off=0; $off < 32/$width; ++$off) {
              $str = pack("B*", "0"x32);
              $bits = (1<<$shift);
              vec($str, $off, $width) = $bits;
              $res = unpack("b*",$str);
              $val = unpack("V", $str);
              write;
          }
      }
  }
  format STDOUT =
  vec($_,@#,@#) = @<< == @######### @>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  $off, $width, $bits, $val, $res
  .
  __END__
    

بغض النظر عن بنية الحاسوب التي يعمل عليها، يجب أن يطبع المثال أعلاه الجدول التالي:

                                    0         1         2         3
                     unpack("V",$_) 01234567890123456789012345678901
  ------------------------------------------------------------------
  vec($_, 0, 1) = 1   ==          1 10000000000000000000000000000000
  vec($_, 1, 1) = 1   ==          2 01000000000000000000000000000000
  vec($_, 2, 1) = 1   ==          4 00100000000000000000000000000000
  vec($_, 3, 1) = 1   ==          8 00010000000000000000000000000000
  vec($_, 4, 1) = 1   ==         16 00001000000000000000000000000000
  vec($_, 5, 1) = 1   ==         32 00000100000000000000000000000000
  vec($_, 6, 1) = 1   ==         64 00000010000000000000000000000000
  vec($_, 7, 1) = 1   ==        128 00000001000000000000000000000000
  vec($_, 8, 1) = 1   ==        256 00000000100000000000000000000000
  vec($_, 9, 1) = 1   ==        512 00000000010000000000000000000000
  vec($_,10, 1) = 1   ==       1024 00000000001000000000000000000000
  vec($_,11, 1) = 1   ==       2048 00000000000100000000000000000000
  vec($_,12, 1) = 1   ==       4096 00000000000010000000000000000000
  vec($_,13, 1) = 1   ==       8192 00000000000001000000000000000000
  vec($_,14, 1) = 1   ==      16384 00000000000000100000000000000000
  vec($_,15, 1) = 1   ==      32768 00000000000000010000000000000000
  vec($_,16, 1) = 1   ==      65536 00000000000000001000000000000000
  vec($_,17, 1) = 1   ==     131072 00000000000000000100000000000000
  vec($_,18, 1) = 1   ==     262144 00000000000000000010000000000000
  vec($_,19, 1) = 1   ==     524288 00000000000000000001000000000000
  vec($_,20, 1) = 1   ==    1048576 00000000000000000000100000000000
  vec($_,21, 1) = 1   ==    2097152 00000000000000000000010000000000
  vec($_,22, 1) = 1   ==    4194304 00000000000000000000001000000000
  vec($_,23, 1) = 1   ==    8388608 00000000000000000000000100000000
  vec($_,24, 1) = 1   ==   16777216 00000000000000000000000010000000
  vec($_,25, 1) = 1   ==   33554432 00000000000000000000000001000000
  vec($_,26, 1) = 1   ==   67108864 00000000000000000000000000100000
  vec($_,27, 1) = 1   ==  134217728 00000000000000000000000000010000
  vec($_,28, 1) = 1   ==  268435456 00000000000000000000000000001000
  vec($_,29, 1) = 1   ==  536870912 00000000000000000000000000000100
  vec($_,30, 1) = 1   == 1073741824 00000000000000000000000000000010
  vec($_,31, 1) = 1   == 2147483648 00000000000000000000000000000001
  vec($_, 0, 2) = 1   ==          1 10000000000000000000000000000000
  vec($_, 1, 2) = 1   ==          4 00100000000000000000000000000000
  vec($_, 2, 2) = 1   ==         16 00001000000000000000000000000000
  vec($_, 3, 2) = 1   ==         64 00000010000000000000000000000000
  vec($_, 4, 2) = 1   ==        256 00000000100000000000000000000000
  vec($_, 5, 2) = 1   ==       1024 00000000001000000000000000000000
  vec($_, 6, 2) = 1   ==       4096 00000000000010000000000000000000
  vec($_, 7, 2) = 1   ==      16384 00000000000000100000000000000000
  vec($_, 8, 2) = 1   ==      65536 00000000000000001000000000000000
  vec($_, 9, 2) = 1   ==     262144 00000000000000000010000000000000
  vec($_,10, 2) = 1   ==    1048576 00000000000000000000100000000000
  vec($_,11, 2) = 1   ==    4194304 00000000000000000000001000000000
  vec($_,12, 2) = 1   ==   16777216 00000000000000000000000010000000
  vec($_,13, 2) = 1   ==   67108864 00000000000000000000000000100000
  vec($_,14, 2) = 1   ==  268435456 00000000000000000000000000001000
  vec($_,15, 2) = 1   == 1073741824 00000000000000000000000000000010
  vec($_, 0, 2) = 2   ==          2 01000000000000000000000000000000
  vec($_, 1, 2) = 2   ==          8 00010000000000000000000000000000
  vec($_, 2, 2) = 2   ==         32 00000100000000000000000000000000
  vec($_, 3, 2) = 2   ==        128 00000001000000000000000000000000
  vec($_, 4, 2) = 2   ==        512 00000000010000000000000000000000
  vec($_, 5, 2) = 2   ==       2048 00000000000100000000000000000000
  vec($_, 6, 2) = 2   ==       8192 00000000000001000000000000000000
  vec($_, 7, 2) = 2   ==      32768 00000000000000010000000000000000
  vec($_, 8, 2) = 2   ==     131072 00000000000000000100000000000000
  vec($_, 9, 2) = 2   ==     524288 00000000000000000001000000000000
  vec($_,10, 2) = 2   ==    2097152 00000000000000000000010000000000
  vec($_,11, 2) = 2   ==    8388608 00000000000000000000000100000000
  vec($_,12, 2) = 2   ==   33554432 00000000000000000000000001000000
  vec($_,13, 2) = 2   ==  134217728 00000000000000000000000000010000
  vec($_,14, 2) = 2   ==  536870912 00000000000000000000000000000100
  vec($_,15, 2) = 2   == 2147483648 00000000000000000000000000000001
  vec($_, 0, 4) = 1   ==          1 10000000000000000000000000000000
  vec($_, 1, 4) = 1   ==         16 00001000000000000000000000000000
  vec($_, 2, 4) = 1   ==        256 00000000100000000000000000000000
  vec($_, 3, 4) = 1   ==       4096 00000000000010000000000000000000
  vec($_, 4, 4) = 1   ==      65536 00000000000000001000000000000000
  vec($_, 5, 4) = 1   ==    1048576 00000000000000000000100000000000
  vec($_, 6, 4) = 1   ==   16777216 00000000000000000000000010000000
  vec($_, 7, 4) = 1   ==  268435456 00000000000000000000000000001000
  vec($_, 0, 4) = 2   ==          2 01000000000000000000000000000000
  vec($_, 1, 4) = 2   ==         32 00000100000000000000000000000000
  vec($_, 2, 4) = 2   ==        512 00000000010000000000000000000000
  vec($_, 3, 4) = 2   ==       8192 00000000000001000000000000000000
  vec($_, 4, 4) = 2   ==     131072 00000000000000000100000000000000
  vec($_, 5, 4) = 2   ==    2097152 00000000000000000000010000000000
  vec($_, 6, 4) = 2   ==   33554432 00000000000000000000000001000000
  vec($_, 7, 4) = 2   ==  536870912 00000000000000000000000000000100
  vec($_, 0, 4) = 4   ==          4 00100000000000000000000000000000
  vec($_, 1, 4) = 4   ==         64 00000010000000000000000000000000
  vec($_, 2, 4) = 4   ==       1024 00000000001000000000000000000000
  vec($_, 3, 4) = 4   ==      16384 00000000000000100000000000000000
  vec($_, 4, 4) = 4   ==     262144 00000000000000000010000000000000
  vec($_, 5, 4) = 4   ==    4194304 00000000000000000000001000000000
  vec($_, 6, 4) = 4   ==   67108864 00000000000000000000000000100000
  vec($_, 7, 4) = 4   == 1073741824 00000000000000000000000000000010
  vec($_, 0, 4) = 8   ==          8 00010000000000000000000000000000
  vec($_, 1, 4) = 8   ==        128 00000001000000000000000000000000
  vec($_, 2, 4) = 8   ==       2048 00000000000100000000000000000000
  vec($_, 3, 4) = 8   ==      32768 00000000000000010000000000000000
  vec($_, 4, 4) = 8   ==     524288 00000000000000000001000000000000
  vec($_, 5, 4) = 8   ==    8388608 00000000000000000000000100000000
  vec($_, 6, 4) = 8   ==  134217728 00000000000000000000000000010000
  vec($_, 7, 4) = 8   == 2147483648 00000000000000000000000000000001
  vec($_, 0, 8) = 1   ==          1 10000000000000000000000000000000
  vec($_, 1, 8) = 1   ==        256 00000000100000000000000000000000
  vec($_, 2, 8) = 1   ==      65536 00000000000000001000000000000000
  vec($_, 3, 8) = 1   ==   16777216 00000000000000000000000010000000
  vec($_, 0, 8) = 2   ==          2 01000000000000000000000000000000
  vec($_, 1, 8) = 2   ==        512 00000000010000000000000000000000
  vec($_, 2, 8) = 2   ==     131072 00000000000000000100000000000000
  vec($_, 3, 8) = 2   ==   33554432 00000000000000000000000001000000
  vec($_, 0, 8) = 4   ==          4 00100000000000000000000000000000
  vec($_, 1, 8) = 4   ==       1024 00000000001000000000000000000000
  vec($_, 2, 8) = 4   ==     262144 00000000000000000010000000000000
  vec($_, 3, 8) = 4   ==   67108864 00000000000000000000000000100000
  vec($_, 0, 8) = 8   ==          8 00010000000000000000000000000000
  vec($_, 1, 8) = 8   ==       2048 00000000000100000000000000000000
  vec($_, 2, 8) = 8   ==     524288 00000000000000000001000000000000
  vec($_, 3, 8) = 8   ==  134217728 00000000000000000000000000010000
  vec($_, 0, 8) = 16  ==         16 00001000000000000000000000000000
  vec($_, 1, 8) = 16  ==       4096 00000000000010000000000000000000
  vec($_, 2, 8) = 16  ==    1048576 00000000000000000000100000000000
  vec($_, 3, 8) = 16  ==  268435456 00000000000000000000000000001000
  vec($_, 0, 8) = 32  ==         32 00000100000000000000000000000000
  vec($_, 1, 8) = 32  ==       8192 00000000000001000000000000000000
  vec($_, 2, 8) = 32  ==    2097152 00000000000000000000010000000000
  vec($_, 3, 8) = 32  ==  536870912 00000000000000000000000000000100
  vec($_, 0, 8) = 64  ==         64 00000010000000000000000000000000
  vec($_, 1, 8) = 64  ==      16384 00000000000000100000000000000000
  vec($_, 2, 8) = 64  ==    4194304 00000000000000000000001000000000
  vec($_, 3, 8) = 64  == 1073741824 00000000000000000000000000000010
  vec($_, 0, 8) = 128 ==        128 00000001000000000000000000000000
  vec($_, 1, 8) = 128 ==      32768 00000000000000010000000000000000
  vec($_, 2, 8) = 128 ==    8388608 00000000000000000000000100000000
  vec($_, 3, 8) = 128 == 2147483648 00000000000000000000000000000001
    
يسلك سلوك wait(2) على نظامك: حيث ينتظر انتهاء عملية وليدة ويعيد معرف العملية (pid) للعملية المنتهية، أو -1 إذا لم يكن هناك عمليات وليدة. تُعاد الحالة في $? و "${^CHILD_ERROR_NATIVE}". لاحظ أن قيمة الإعادة -1 قد تعني أن العمليات الوليدة تُحصد آليًا، كما هو موضح في perlipc.

إذا استخدمت "wait" في معالجك لـ $SIG{CHLD}، فقد ينتظر عن طريق الخطأ العملية الوليدة المنشأة بواسطة "qx" أو "system". راجع perlipc للتفاصيل.

يكافئ "waitpid(-1, 0)".

قضايا قابلية النقل: "wait" في perlport.

ينتظر انتهاء عملية وليدة معينة ويعيد معرف العملية (pid) للعملية المنتهية، أو -1 إذا لم توجد مثل هذه العملية الوليدة. يمكن للانتظار غير المقيد (مع WNOHANG في FLAGS) أن يعيد 0 إذا كانت هناك عمليات وليدة تطابق PID ولكن لم ينتهِ أي منها بعد. تُعاد الحالة في $? و "${^CHILD_ERROR_NATIVE}".

تشير قيمة PID البالغة 0 إلى انتظار أي عملية وليدة يكون معرف مجموعة العمليات الخاص بها مساويًا لمعرف العملية الحالية. تشير قيمة PID الأقل من -1 إلى انتظار أي عملية وليدة يكون معرف مجموعة العمليات الخاص بها مساويًا لـ -PID. تشير قيمة PID البالغة -1 إلى انتظار أي عملية وليدة.

إذا قلت

    use POSIX ":sys_wait_h";
    my $kid;
    do {
        $kid = waitpid(-1, WNOHANG);
    } while $kid > 0;
    

أو

    1 while waitpid(-1, WNOHANG) > 0;
    

عندها يمكنك إجراء انتظار غير حاجب لجميع العمليات الزومبي (zombie) المعلقة (انظر "WAIT" في POSIX). الانتظار غير الحاجب متاح في الأجهزة التي تدعم استدعاءات النظام إما waitpid(2) أو wait4(2). ومع ذلك، فإن انتظار معرف عملية (pid) محدد مع وسم FLAGS بقيمة 0 مُنفذ في كل مكان. (تحاكي Perl استدعاء النظام عن طريق تذكر قيم حالة العمليات التي خرجت ولكن لم تُحصد بواسطة سكربت Perl بعد.)

لاحظ أنه في بعض الأنظمة، قد تعني القيمة المعادة -1 أن العمليات الابنة تُحصد آليًا. انظر perlipc للتفاصيل ولأمثلة أخرى.

مشكلات النقلية: "waitpid" في perlport.

تعيد true إذا كان سياق الروتين الفرعي الذي يُنفذ حاليًا أو "eval" يبحث عن قيمة قائمة. وتعيد false إذا كان السياق يبحث عن قيمة سلمية (scalar). وتعيد القيمة غير المعرفة (undefined) إذا كان السياق لا يبحث عن قيمة (سياق فارغ/void).

    return unless defined wantarray; # لا تجشم نفسك عناء فعل المزيد
    my @a = complex_calculation();
    return wantarray ? @a : "@a";
    

نتيجة "wantarray" غير محددة في المستوى الأعلى لملف، أو في كتل "BEGIN" أو "UNITCHECK" أو "CHECK" أو "INIT" أو "END"، أو في تابع "DESTROY".

كان ينبغي تسمية هذه الدالة wantlist() بدلاً من ذلك.

تطلق تحذيرًا، عادةً عن طريق طباعته إلى "STDERR". تترجم "warn" معاملها LIST بنفس طريقة "die"، ولكنها تختلف قليلاً في قيمتها المبدئية عندما تكون LIST فارغة أو تنتج سلسلة فارغة. إذا كانت فارغة وكان $@ يحتوي بالفعل على قيمة استثناء، فتُستخدم تلك القيمة بعد إلحاق "\t...caught" بها. أما إذا كانت فارغة وكان $@ فارغًا أيضًا، فتُستخدم السلسلة "Warning: Something's wrong".

مبدئيًا، يتم تحويل الاستثناء المشتق من المعامل LIST إلى سلسلة نصية ويُطبع إلى "STDERR". يمكن تغيير هذا السلوك عن طريق تثبيت معالج $SIG{__WARN__}. إذا كان هناك مثل هذا المعالج فلن تُطبع أي رسالة آلياً؛ تقع على عاتق المعالج مسؤولية التعامل مع الاستثناء كما يراه مناسباً (مثل، على سبيل المثال، تحويله إلى "die"). لذلك يجب على معظم المعالجين الترتيب لعرض التحذيرات التي ليسوا مستعدين للتعامل معها فعلياً، عن طريق استدعاء "warn" مرة أخرى في المعالج. لاحظ أن هذا آمن تماماً ولن ينتج حلقة لا نهائية، بما أن خطافات "__WARN__" لا تُستدعى من داخل أحدها.

ستجد هذا السلوك مختلفاً قليلاً عن سلوك معالجات $SIG{__DIE__} (التي لا تخفي نص الخطأ، ولكن يمكنها بدلاً من ذلك استدعاء "die" مرة أخرى لتغييره).

يوفر استخدام معالج "__WARN__" طريقة قوية لإسكات جميع التحذيرات (حتى تلك التي تسمى إجبارية). مثال:

    # wipe out *all* compile-time warnings
    BEGIN { $SIG{'__WARN__'} = sub { warn $_[0] if $DOWARN } }
    my $foo = 10;
    my $foo = 20;          # no warning about duplicate my $foo,
                           # but hey, you asked for it!
    # no compile-time or run-time warnings before here
    $DOWARN = 1;
    # run-time warnings enabled after here
    warn "\$foo is alive and $foo!";     # does show up
    

انظر perlvar للحصول على تفاصيل حول ضبط مدخلات %SIG ولمزيد من الأمثلة. انظر وحدة Carp لأنواع أخرى من التحذيرات باستخدام دالتي "carp" و "cluck" التابعتين لها.

write FILEHANDLE
write EXPR
تكتب سجلاً منسقًا (ربما متعدد الأسطر) إلى FILEHANDLE المحدد، باستخدام التنسيق المرتبط بهذا الملف. مبدئيًا، التنسيق الخاص بملف هو التنسيق الذي يحمل نفس اسم مقبض الملف، ولكن يمكن ضبط تنسيق قناة الإخراج الحالية (انظر دالة "select") صراحةً عن طريق تعيين اسم التنسيق إلى المتغير $~.

تتم معالجة بداية النموذج آليًا: إذا لم تكن هناك مساحة كافية في الصفحة الحالية للسجل المنسق، فتُقدم الصفحة عن طريق كتابة تغذية نموذج (form feed) ويُستخدم تنسيق خاص لبداية الصفحة لتنسيق ترويسة الصفحة الجديدة قبل كتابة السجل. مبدئيًا، تنسيق بداية الصفحة هو اسم مقبض الملف مع إلحاق "_TOP" به، أو "top" في الحزمة الحالية إذا لم يكن الأول موجودًا. قد يمثل هذا مشكلة مع مقابض الملفات الحية تلقائيًا (autovivified)، ولكن يمكن ضبطه ديناميكيًا على التنسيق الذي تختاره عن طريق تعيين الاسم للمتغير $^ أثناء تحديد مقبض الملف هذا. عدد الأسطر المتبقية في الصفحة الحالية موجود في المتغير "$-"، والذي يمكن ضبطه على 0 لفرض صفحة جديدة.

إذا لم يُحدد FILEHANDLE، يذهب الإخراج إلى قناة الإخراج المبدئية الحالية، والتي تبدأ كـ STDOUT ولكن يمكن تغييرها بواسطة عامل "select". إذا كان FILEHANDLE عبارة عن EXPR، فتُقيم التعبير وتُستخدم السلسلة الناتجة للبحث عن اسم FILEHANDLE في وقت التشغيل. لمزيد من المعلومات حول التنسيقات، انظر perlform.

لاحظ أن write ليست عكس "read". لسوء الحظ.

عامل الترجمة الحرفية (transliteration). هو نفسه "tr///". انظر "Quote-Like Operators" في perlop.

الكلمات المفتاحية غير الدالية حسب الإحالة المرجعية

perldata

__DATA__
__END__
هذه الكلمات المفتاحية موثقة في "Special Literals" في perldata.

perlmod

النهاية
هذه الكلمات المفتاحية لمرحلة التصريف (compile phase) موثقة في "BEGIN, UNITCHECK, CHECK, INIT and END" في perlmod.

perlobj

الكلمة المفتاحية لهذه الطريقة (method) موثقة في "Destructors" في perlobj.

perlop

و
أو
هذه العوامل موثقة في perlop.

perlsub

هذه الكلمة المفتاحية موثقة في "Autoloading" في perlsub.

perlsyn

لـ
كلمات التحكم في التدفق (flow-control) هذه موثقة في "Compound Statements" في perlsyn.
كلمة "else if" تُكتب "elsif" في Perl. لا توجد "elif" أو "else if" أيضاً. إنها تحلل "elseif"، ولكن فقط لتحذيرك من عدم استخدامها.

انظر توثيق كلمات التحكم في التدفق في "Compound Statements" في perlsyn.

كلمات التحكم في التدفق هذه المتعلقة بميزة التحويل (switch) التجريبية موثقة في "Switch Statements" في perlsyn.
كلمات التحكم في التدفق هذه المتعلقة بميزة "try" التجريبية موثقة في "Try Catch Exception Handling" في perlsyn.
الكلمة المفتاحية للتحكم في التدفق هذه المتعلقة بميزة "defer" التجريبية موثقة في "defer blocks" في perlsyn.
كتلة phaser المتعلقة بالفئة (class) هذه موثقة في perlclass.

ترجمة

تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.

11 يوليو 2025 بيرل v5.42.0