| PERLFUNC(1) | دليل مرجع مبرمجي بيرل | PERLFUNC(1) |
الاسم¶
perlfunc - دوال بيرل المدمجة
الوصف¶
يمكن للدوال في هذا القسم أن تعمل كحدود في تعبير برمجي. وهي تنقسم إلى فئتين رئيسيتين: معاملات القائمة (list operators) والمعاملات الأحادية المسماة (named unary operators). وتختلف هذه المعاملات في علاقة أسبقيتها مع الفاصلة التي تليها. (انظر جدول الأسبقية في perlop). تأخذ معاملات القائمة أكثر من معامل واحد، بينما لا يمكن للمعاملات الأحادية أن تأخذ أكثر من معامل واحد أبدًا. وبالتالي، تنهي الفاصلة معامل المشغل الأحادي، لكنها تكتفي بالفصل بين معاملات مشغل القائمة. يوفر المشغل الأحادي عمومًا سياقًا قياسيًا (scalar context) لمعامله، بينما قد يوفر مشغل القائمة سياقًا قياسيًا أو سياق قائمة لمعاملاته. إذا كان يوفر كلاهما، فإن المعاملات القياسية تأتي أولاً وتتبعها معامل القائمة، ولا يمكن أن يكون هناك سوى معامل قائمة واحد فقط من هذا القبيل. على سبيل المثال، تحتوي الدوال "splice" على ثلاثة معاملات قياسية تتبعها قائمة، بينما تحتوي "gethostbyname" على أربعة معاملات قياسية.
في أوصاف بناء الجملة التي تلي ذلك، تظهر معاملات القائمة التي تتوقع قائمة (وتوفر سياق قائمة لعناصر القائمة) مع استخدام LIST كمعامل. قد تتكون هذه القائمة من أي مزيج من المعاملات القياسية أو قيم القائمة؛ وسيتم تضمين قيم القائمة في القائمة كما لو تم إقحام كل عنصر فردي في تلك النقطة من القائمة، مما يشكل قيمة قائمة أطول أحادية البعد. يجب أن تفصل الفواصل بين العناصر الحرفية للقائمة.
يمكن استخدام أي دالة في القائمة أدناه إما بوجود أقواس حول معاملاتها أو بدونها. (تحذف أوصاف بناء الجملة الأقواس). إذا استخدمت الأقواس، فإن القاعدة البسيطة التي قد تكون مفاجئة أحيانًا هي: إذا كانت *تبدو* كدالة، فهي إذًا *دالة*، ولا تهم الأسبقية حينها. بخلاف ذلك، فهي معامل قائمة أو معامل أحادي، وتصبح الأسبقية مهمة. لا تُحتسب المسافات البيضاء بين الدالة والقوس الأيسر، لذا عليك توخي الحذر أحيانًا:
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)، وفي سياق القائمة عن طريق إرجاع قائمة فارغة.
تذكر القاعدة المهمة التالية: **لا توجد قاعدة** تربط سلوك تعبير ما في سياق القائمة بسلوكه في السياق القياسي، أو العكس. قد يقوم التعبير بشيئين مختلفين تمامًا. يقرر كل معامل ودالة نوع القيمة الأكثر ملاءمة لإرجاعها في السياق القياسي. تعيد بعض المعاملات طول القائمة التي كان سيتم إرجاعها في سياق القائمة. وتعيد بعض المعاملات القيمة الأولى في القائمة. وتعيد معاملات أخرى القيمة الأخيرة في القائمة. بينما تعيد بعض المعاملات عدد العمليات الناجحة. بشكل عام، تقوم هذه الدوال بما تريده، ما لم تكن تريد الاتساق.
تختلف المصفوفة المسماة في السياق القياسي تمامًا عما قد يبدو للوهلة الأولى أنه قائمة في سياق قياسي. لا يمكنك جعل قائمة مثل "(1,2,3)" تتواجد في سياق قياسي، لأن المترجم (compiler) يعرف السياق في وقت الترجمة. سيقوم المترجم بتوليد معامل الفاصلة القياسي هناك، وليس نسخة دمج القوائم من الفاصلة. وهذا يعني أنها لم تكن قائمة من الأساس.
بشكل عام، الدوال في بيرل التي تعمل كأغلفة لاستدعاءات النظام (system calls) التي تحمل نفس الاسم (مثل chown(2) و fork(2) و closedir(2) وغيرها) تعيد قيمة حقيقية (true) عند نجاحها وتعيد "undef" خلاف ذلك، كما هو مذكور عادةً في الأوصاف أدناه. هذا يختلف عن واجهات لغة C التي تعيد -1 عند الفشل. تشمل الاستثناءات لهذه القاعدة "wait" و "waitpid" و "syscall". كما تقوم استدعاءات النظام بتعيين المتغير الخاص $! عند الفشل، بينما لا تفعل الدوال الأخرى ذلك إلا بمحض الصدفة.
يمكن لوحدات الامتداد (Extension modules) أيضًا الارتباط بمحلل بيرل (Perl parser) لتعريف أنواع جديدة من التعبيرات التي تبدأ بكلمات مفتاحية. قد تبدو هذه التعبيرات مثل الدوال، لكنها قد تبدو أيضًا مختلفة تمامًا. يتم تعريف بناء الجملة الذي يلي الكلمة المفتاحية بالكامل بواسطة الامتداد. إذا كنت مطورًا، فراجع "PL_keyword_plugin" في perlapi للتعرف على الآلية. أما إذا كنت تستخدم مثل هذه الوحدة، فراجع توثيق الوحدة للحصول على تفاصيل بناء الجملة الذي تحدده.
دوال بيرل حسب الفئة¶
إليك دوال لغة بيرل (بما في ذلك العناصر التي تبدو كدوال، مثل بعض الكلمات المفتاحية والمعاملات المسماة) مرتبة حسب الفئة. تظهر بعض الدوال في أكثر من موضع. أي تحذيرات، بما في ذلك تلك الناتجة عن الكلمات المفتاحية، موصوفة في 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"
- Functions for real @ARRAYs
- "each", "keys", "pop", "push", "shift", "splice", "unshift", "values"
- دوال لبيانات القوائم
- "grep", "join", "map", "qw//", "reverse", "sort", "unpack"
- Functions for real %HASHes
- "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
- اختبار
ملف، حيث X
هو أحد
الأحرف
المدرجة
أدناه. يأخذ
هذا
المعامل
الأحادي
وسيطًا
واحدًا،
سواء كان
اسم ملف، أو
مقبض ملف،
أو مقبض
دليل،
ويختبر
الملف
المرتبط
لمعرفة ما
إذا كان
هناك شيء ما
صحيحًا
بشأنه. إذا
حُذف
الوسيط،
يختبر
$_،
باستثناء
"-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 (قوائم التحكم في الوصول)، وأنظمة الملفات للقراءة فقط، وتنسيقات الملفات التنفيذية غير المعترف بها. لاحظ أن استخدام هذه المعاملات الستة المحددة للتحقق مما إذا كانت بعض العمليات ممكنة هو عادة خطأ، لأنه قد يكون عرضة لظروف التسابق.
لاحظ أيضًا أنه بالنسبة للمستخدم الخارق (superuser) على أنظمة الملفات المحلية، فإن اختبارات "-r" و "-R" و "-w" و "-W" تعيد دائمًا 1، و "-x" و "-X" تعيد 1 إذا ضُبط أي بت تنفيذ في الوضع. وبالتالي قد تحتاج السكربتات التي يشغلها المستخدم الخارق إلى إجراء "stat" لتحديد الوضع الفعلي للملف، أو تعيين uid الفعلي مؤقتًا لشيء آخر.
إذا كنت تستخدم ACLs، فهناك pragma يسمى "filetest" قد يعطي نتائج أكثر دقة من بتات وضع "stat" المجردة. عند استخدام "use filetest 'access'"، تختبر اختبارات الملفات المذكورة أعلاه ما إذا كان يمكن (أو لا يمكن) منح الإذن باستخدام عائلة نداءات النظام access(2). لاحظ أيضًا أن اختبارات "-x" و "-X" قد تعيد صوابًا بموجب هذا الـ pragma حتى لو لم تكن هناك بتات إذن تنفيذ مضبوطة (ولا أي ACLs إذن تنفيذ إضافية). يعود هذا الغرابة إلى تعريفات نداءات النظام الأساسية. لاحظ أيضًا أنه نظرًا لتنفيذ "use filetest 'access'"، فإن مقبض الملف الخاص "_" لن يخزن (cache) نتائج اختبارات الملفات عندما يكون هذا الـ pragma ساري المفعول. اقرأ توثيق pragma الـ "filetest" لمزيد من المعلومات.
يعمل اختباري "-T" و "-B" على النحو التالي. يُفحص المقطع الأول أو ما شابه من الملف لمعرفة ما إذا كان UTF-8 صالحًا يتضمن أحرفًا غير ASCII. إذا كان الأمر كذلك، فهو ملف "-T". خلاف ذلك، يُفحص نفس الجزء من الملف بحثًا عن أحرف غريبة مثل أكواد التحكم الغريبة أو الأحرف التي تم ضبط البت العالي فيها. إذا كان أكثر من ثلث الأحرف غريبًا، فهو ملف "-B"؛ وإلا فهو ملف "-T". وأيضًا، أي ملف يحتوي على بايت صفري في الجزء المفحوص يعتبر ملفًا ثنائيًا. (إذا نُفذ ضمن نطاق use locale يتضمن "LC_CTYPE"، فإن الأحرف الغريبة هي أي شيء ليس قابلاً للطباعة ولا مسافة في الإعدادات المحلية الحالية.) إذا استُخدم "-T" أو "-B" على مقبض ملف، يُفحص مخزن IO المؤقت الحالي بدلاً من المقطع الأول. كلاهما يعيد صوابًا في ملف فارغ، أو ملف عند 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
- abs
- يعيد القيمة المطلقة لوسيطه. إذا حُذفت القيمة (VALUE)، يستخدم $_.
- accept NEWSOCKET,GENERICSOCKET
- يقبل اتصال
مقبس وارد،
تمامًا كما
يفعل accept(2).
يعيد
العنوان
المجمع (packed address)
إذا نجح،
وخطأ بخلاف
ذلك. انظر
المثال في
"Sockets: Client/Server Communication" في perlipc.
في الأنظمة التي تدعم علم الإغلاق عند التنفيذ (close-on-exec) في الملفات، سيُضبط العلم لواصف الملف المفتوح حديثًا، كما هو محدد بواسطة قيمة $^F. راجع "$^F" في perlvar.
- alarm SECONDS
- alarm
- يرتب
لتسليم
إشارة SIGALRM إلى
هذه
العملية
بعد انقضاء
عدد محدد من
ثواني
الساعة
الحائطية.
إذا لم
تُحدد
الثواني (SECONDS)،
تُستخدم
القيمة
المخزنة في
$_. (في بعض
الآلات،
لسوء الحظ،
قد يكون
الوقت
المنقضي
أقل أو أكثر
بمقدار
ثانية
واحدة مما
حددته بسبب
كيفية عد
الثواني،
وقد يؤخر
جدولة
العملية
تسليم
الإشارة
بشكل أكبر.)
يمكن لمؤقت واحد فقط أن يعمل في وقت واحد. كل نداء يعطل المؤقت السابق، ويمكن تقديم وسيط بقيمة 0 لإلغاء المؤقت السابق دون بدء مؤقت جديد. القيمة المعادة هي مقدار الوقت المتبقي في المؤقت السابق.
بالنسبة للتأخيرات ذات الدقة الأعلى من ثانية واحدة، توفر وحدة Time::HiRes (من CPAN، وبدءًا من الإصدار 5.8 من Perl أصبحت جزءًا من التوزيع القياسي) دالة "ualarm". يمكنك أيضًا استخدام نسخة Perl ذات الوسائط الأربعة من "select" مع ترك الوسائط الثلاثة الأولى غير محددة، أو قد تتمكن من استخدام واجهة "syscall" للوصول إلى setitimer(2) إذا كان نظامك يدعم ذلك. راجع perlfaq8 لمزيد من التفاصيل.
عادة ما يكون من الخطأ الخلط بين نداءات "alarm" و "sleep"، لأن "sleep" قد تكون منفذة داخليًا في نظامك باستخدام "alarm".
إذا كنت تريد استخدام "alarm" لإنهاء نداء نظام عند انتهاء الوقت، فأنت بحاجة إلى استخدام زوج "eval"/"die". لا يمكنك الاعتماد على التنبيه في التسبب في فشل نداء النظام مع ضبط $! على "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.
- atan2 Y,X
- تُرجع ظل
الزاوية
العكسي لـ Y/X
في النطاق
من -PI إلى PI.
بالنسبة لعملية الظل، يمكنك استخدام دالة "Math::Trig::tan"، أو استخدام العلاقة المعروفة:
sub tan { sin($_[0]) / cos($_[0]) }القيمة المعادة لـ "atan2(0,0)" محددة حسب التنفيذ؛ راجع صفحة الدليل atan2(3) الخاصة بنظامك لمزيد من المعلومات.
مشكلات قابلية النقل: "atan2" في perlport.
- bind SOCKET,NAME
- يربط عنوان شبكة بمقبس، تمامًا كما يفعل bind(2). يعيد قيمة صواب إذا نجح، وخطأ في حال خلاف ذلك. ينبغي أن يكون NAME عنوانًا محزومًا من النوع المناسب للمقبس. راجع الأمثلة في "Sockets: Client/Server Communication" في perlipc.
- binmode FILEHANDLE, LAYER
- binmode FILEHANDLE
- يرتب لـ FILEHANDLE
ليُقرأ أو
يُكتب في
نمط
"ثنائي" أو
"نصي" على
الأنظمة
التي تميز
فيها
مكتبات وقت
التشغيل
بين
الملفات
الثنائية
والنصية.
إذا كان FILEHANDLE
تعبيرًا،
تُؤخذ
القيمة على
أنها اسم
واصف الملف.
يعيد قيمة
صواب عند
النجاح،
وإلا فإنه
يعيد "undef"
ويضبط $!
(errno).
في بعض الأنظمة (بشكل عام، الأنظمة القائمة على DOS و Windows) تكون "binmode" ضرورية عندما لا تعمل مع ملف نصي. من أجل قابلية النقل، من الجيد استخدامها دائمًا عندما يكون ذلك مناسبًا، وعدم استخدامها مطلقًا عندما لا يكون مناسبًا. أيضًا، يمكن للمستخدمين ضبط الإدخال/الإخراج الخاص بهم ليكون مبدئيًا بترميز Unicode بتنسيق UTF8، وليس بايتات.
بمعنى آخر: بغض النظر عن المنصة، استخدم "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 REF,CLASSNAME
- bless REF
- تخبر "bless" لغة Perl بتمييز العنصر المشار إليه بواسطة "REF" ككائن في حزمة. يُفضل دائمًا إصدار المعاملين من "bless" ما لم يكن هناك سبب محدد لعدم استخدامه.
- مباركة (Bless)
العنصر
المشار
إليه في
حزمة محددة
(النموذج
الموصى به):
bless $ref, $package;يضيف نموذج المعاملين الكائن إلى الحزمة المحددة كمعامل ثانٍ.
- مباركة
العنصر
المشار
إليه في
الحزمة
"main":
bless $ref, "";إذا كان المعامل الثاني سلسلة فارغة، تضيف "bless" الكائن إلى الحزمة "main".
- مباركة
العنصر
المشار
إليه في
الحزمة
الحالية
(غير قابل
للتوريث):
bless $ref;إذا استُخدمت "bless" بدون معاملها الثاني، يُنشأ الكائن في الحزمة الحالية. ينبغي دائمًا توفير المعامل الثاني إذا كان من الممكن لصنف مشتق أن يرث طريقة تنفذ "bless". نظرًا لأنها مصدر محتمل للعلل، لا يُنصح باستخدام "bless" بمعامل واحد.
راجع perlobj لمزيد من المعلومات حول مباركة (blessing) الكائنات.
تعيد "bless" معاملها الأول، المرجع الموفر، كقيمة للدالة؛ وبما أن "bless" هي عادة آخر شيء يُنفذ في المنشئات، فهذا يعني أن المرجع للكائن يُعاد كقيمة للمنشئ ويسمح لـ المستدعِي باستخدام هذا الكائن المعاد فورًا في استدعاءات الطرق.
ينبغي أن يكون "CLASSNAME" دائمًا اسمًا مختلط الحالة (mixed-case)، حيث إن الأسماء المكتوبة بالكامل بأحرف كبيرة أو صغيرة مخصصة لأنواع Perl المدمجة والبرغمات على التوالي. تجنب إنشاء أسماء حزم بأحرف كبيرة فقط أو صغيرة فقط لمنع الارتباك.
تجنب أيضًا مباركة (blessing) الأشياء في اسم صنف 0؛ سيؤدي ذلك إلى فشل الكود الذي يتحقق (خطأً) من نتيجة "ref" لمعرفة ما إذا كان المرجع "مباركًا"، حيث ستُعاد القيمة "0" وهي قيمة خاطئة.
راجع "Perl Modules" في perlmod لمزيد من التفاصيل.
- break
- الخروج من
كتلة
"given".
"break" متاحة فقط إذا كانت ميزة "switch" مفعلة أو إذا كانت مسبوقة بـ "CORE::". تُفعل ميزة "switch" آليًا بتصريح "use v5.10" (أو أعلى) في النطاق الحالي.
- caller EXPR
- caller
- يعيد سياق
استدعاء
روتين Perl
الفرعي
الحالي
الصرف. في
السياق
القياسي،
يعيد اسم
حزمة
المستدعِي
إذا كان
هناك
مستدعٍ (أي
إذا كنا في
روتين فرعي
أو "eval" أو
"require")
والقيمة
غير
المحددة
بخلاف ذلك.
لا يعيد
"caller"
روتينات XS
الفرعية
ويتم
تخطيها.
سيظهر
الروتين
الفرعي
الصرف
التالي
بدلاً من
روتين 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 هو أقصى جهد، ومخصص للتنقيح أو إنشاء تتبع خلفي، ولا ينبغي الاعتماد عليه. على وجه الخصوص، بما أن @_ يحتوي على أسماء مستعارة لوسائط المستدعِي، فإن Perl لا يأخذ نسخة من @_، لذا سيحتوي @DB::args على التعديلات التي يجريها الروتين الفرعي على @_ أو محتوياته، وليس القيم الأصلية وقت الاستدعاء. @DB::args، مثل @_، لا يحتفظ بمرجع صريح لعناصره، لذا في حالات معينة قد تُحرر عناصره ويُعاد تخصيصها لمتغيرات أخرى أو قيم مؤقتة. أخيرًا، هناك تأثير جانبي للتنفيذ الحالي وهو أن تأثيرات "shift @_" يمكن إبطالها بشكل طبيعي (ولكن ليس "pop @_" أو عمليات دمج أخرى، وليس إذا أُخذ مرجع لـ @_، ومع مراعاة التحذير بشأن العناصر المعاد تخصيصها)، لذا فإن @DB::args هو في الواقع مزيج من الحالة الحالية والحالة الأولية لـ @_. المشتري يحذر.
- chdir EXPR
- chdir FILEHANDLE
- chdir DIRHANDLE
- chdir
- يغير دليل
العمل إلى
EXPR، إذا كان
ذلك ممكنًا.
إذا حُذف EXPR،
يغير إلى
الدليل
المحدد
بواسطة
$ENV{HOME}، إذا
ضُبط؛ وإذا
لم يكن
كذلك، يغير
إلى الدليل
المحدد
بواسطة
$ENV{LOGDIR}.
(بموجب VMS،
يُتحقق
أيضًا من
المتغير
$ENV{'SYS$LOGIN'}،
ويستخدم
إذا ضُبط.)
إذا لم
يُضبط أي
منهما، فإن
"chdir" لا
يفعل شيئًا
ويفشل. يعيد
صوابًا عند
النجاح،
وخطأ بخلاف
ذلك. انظر
المثال تحت
"die".
في الأنظمة التي تدعم fchdir(2)، يمكنك تمرير مقبض ملف أو مقبض دليل كوسيط. في الأنظمة التي لا تدعم fchdir(2)، يؤدي تمرير المقابض إلى إثارة استثناء.
- chmod LIST
- يغير
أذونات
قائمة من
الملفات.
يجب أن يكون
العنصر
الأول من
القائمة هو
الوضع
العددي،
والذي يجب
أن يكون
رقمًا
ثمانيًا،
والذي لا
ينبغي
بالتأكيد
أن يكون
سلسلة من
الأرقام
الثمانية:
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 أو مراجع glob ليتم التعرف عليها؛ تُعتبر الكلمات المجردة أسماء ملفات.
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
- chomp( LIST )
- chomp
- هذا
الإصدار
الأكثر
أمانًا من
"chop" يزيل
أي سلسلة
لاحقة
تتوافق مع
القيمة
الحالية لـ
$/
(المعروف
أيضًا باسم
$INPUT_RECORD_SEPARATOR في
وحدة
"English"). وهو
يعيد
إجمالي عدد
الأحرف
المحذوفة
من جميع
وسائطه.
غالبًا ما
يُستخدم
لإزالة سطر
جديد من
نهاية سجل
إدخال
عندما تكون
قلقًا من أن
السجل
النهائي قد
يفتقد
لسطره
الجديد.
عندما يكون
في وضع
الفقرة
("$/ = ''")،
فإنه يزيل
جميع
الأسطر
الجديدة
اللاحقة من
السلسلة.
عندما يكون
في وضع
الارتشاف (slurp)
("$/ = undef") أو
وضع السجل
ثابت الطول
($/ هو
مرجع لعدد
صحيح أو ما
شابه؛ انظر
perlvar)، فإن
"chomp" لن
يزيل أي
شيء. إذا
حُذف
المتغير
(VARIABLE)، فإنه
يطبق chomp على
$_. مثال:
while (<>) { chomp; # تجنب \n في الحقل الأخير my @array = split(/:/); # ... }إذا كان المتغير (VARIABLE) عبارة عن هش، فإنه يطبق chomp على قيم الهش، ولكن ليس على مفاتيحه، مع إعادة تعيين مكرر "each" في هذه العملية.
يمكنك فعليًا تطبيق chomp على أي شيء يمثل قيمة يسارية (lvalue)، بما في ذلك عملية الإسناد:
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
- chop( LIST )
- chop
- يحذف الحرف
الأخير من
السلسلة
النصية
ويعيد
الحرف
المحذوف.
إنه أكثر
كفاءة
بكثير من
"s/.$//s"
لأنه لا
يفحص
السلسلة
ولا ينسخها.
إذا حُذف
المتغير
(VARIABLE)، فإنه
يحذف من
$_. إذا
كان
المتغير (VARIABLE)
عبارة عن
هش، فإنه
يحذف من قيم
الهش، ولكن
ليس من
مفاتيحه،
مع إعادة
تعيين مكرر
"each" في
هذه
العملية.
يمكنك فعليًا بتر (chop) أي شيء يعد قيمة يسارية (lvalue)، بما في ذلك التعيين.
إذا بترت قائمة، فسيُبتر كل عنصر فيها. وتُعاد قيمة آخر عملية "chop" فقط.
لاحظ أن "chop" تعيد المحرف الأخير. لإعادة كل المحارف باستثناء الأخير، استخدم "substr($string, 0, -1)".
انظر أيضًا "chomp".
- chown LIST
- تغير
المالك
(والمجموعة)
لقائمة من
الملفات.
يجب أن يكون
أول عنصرين
في القائمة
هما معرف
المستخدم
numeric ومعرف
المجموعة
numeric، بهذا
الترتيب.
تُفسر
القيمة -1 في
أي من
الموضعين
بواسطة
معظم
الأنظمة
على أنها
ترك تلك
القيمة دون
تغيير. تعيد
عدد
الملفات
التي غُيرت
بنجاح.
my $cnt = chown $uid, $gid, 'foo', 'bar'; chown $uid, $gid, @filenames;في الأنظمة التي تدعم fchown(2)، يمكنك تمرير مقابض الملفات ضمن الملفات. في الأنظمة التي لا تدعم fchown(2)، يؤدي تمرير مقابض الملفات إلى إثارة استثناء. يجب تمرير مقابض الملفات كـ globs أو مراجع globs ليُتعرف عليها؛ وتُعتبر الكلمات المجردة أسماء ملفات.
إليك مثال يبحث عن معرفات مستخدمين غير رقمية في ملف 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;في معظم الأنظمة، لا يُسمح لك بتغيير ملكية الملف ما لم تكن المستخدم الخارق، رغم أنه ينبغي أن تكون قادرًا على تغيير المجموعة إلى أي من مجموعاتك الثانوية. في الأنظمة غير الآمنة، قد تُخفف هذه القيود، لكن هذا ليس افتراضًا محمولاً. في أنظمة POSIX، يمكنك اكتشاف هذه الحالة بهذه الطريقة:
use POSIX qw(pathconf _PC_CHOWN_RESTRICTED); my $can_chown_giveaway = ! pathconf($path_of_interest, _PC_CHOWN_RESTRICTED);قضايا المحمولية: "chown" في perlport.
- chr NUMBER
- chr
- تعيد
المحرف
الذي يمثله
ذلك الـ NUMBER في
مجموعة
المحارف.
على سبيل
المثال،
chr(65) هي
"A" سواء
في ASCII أو Unicode، و
chr(0x263a) هو
وجه باسم في
Unicode.
تعطي القيم السالبة محرف استبدال Unicode (chr(0xfffd))، باستثناء ما هو تحت موجّه (pragma) البايتات، حيث تُستخدم الثماني بتات المنخفضة من القيمة (مبتورة إلى عدد صحيح).
إذا أُغفل الـ NUMBER، تُستخدم $_.
للعكس، استخدم "ord".
لاحظ أن المحارف من 128 إلى 255 (بما في ذلك) لا تُرمّز داخليًا كمبدئي بصيغة UTF-8 لأسباب تتعلق بالتوافقية مع الإصدارات السابقة.
انظر perlunicode للمزيد حول Unicode.
- chroot FILENAME
- chroot
- تعمل هذه
الدالة مثل
نداء
النظام
الذي يحمل
نفس الاسم:
فهي تجعل
المجلد
المسمى هو
المجلد
الجذر (root)
الجديد
لجميع
مسارات
الملفات
اللاحقة
التي تبدأ
بـ "/"
بواسطة
عمليتك
وجميع
توابعها.
(لا تغير
مجلد العمل
الحالي،
فهو لا
يتأثر).
لأسباب
أمنية،
يقتصر هذا
النداء على
المستخدم
الخارق. إذا
أُغفل الـ
FILENAME، تُجرى
عملية
"chroot" على
$_.
ملاحظة: من الإلزامي للأمن القيام بـ chdir("/") ("chdir" إلى المجلد الجذر) فورًا بعد "chroot"، وإلا فقد يكون مجلد العمل الحالي خارج الجذر الجديد.
قضايا المحمولية: "chroot" في perlport.
- class NAMESPACE
- class NAMESPACE VERSION
- class NAMESPACE BLOCK
- class NAMESPACE VERSION BLOCK
- تعلن عن الـ BLOCK أو بقية وحدة التجميع ككائن في مساحة الأسماء المعطاة، والتي تنفذ فئة كائن (object class). يسلك هذا سلوكًا مشابهًا لـ "package"، باستثناء أن الحزمة المنشأة حديثًا تسلك سلوك الفئة.
- close FILEHANDLE
- close
- تغلق الملف
أو الأنبوب
المرتبط
بمقبض
الملف،
وتفرغ
خبيئات
الإدخال
والإخراج،
وتغلق واصف
ملف النظام.
تعيد قيمة
صواب إذا
نجحت تلك
العمليات،
وإذا لم
يبلغ عن أي
خطأ بواسطة
أي طبقة PerlIO،
ولم يكن
هناك خطأ
موجود
مسبقًا على
مقبض الملف.
إذا كان هناك خطأ موجود مسبقًا على مقبض الملف، فستعيد close قيمة خطأ وسيُضبط $! على الخطأ الناتج عن العملية الفاشلة، لذا يمكنك استخدام قيمته بأمان عند التبليغ عن الخطأ.
تغلق مقبض الملف المحدد حاليًا إذا أُغفل المعطى.
ليس عليك إغلاق FILEHANDLE إذا كنت ستجري عملية "open" أخرى عليه فورًا، لأن "open" تغلقه نيابة عنك. (انظر "open"). ومع ذلك، فإن الإغلاق الصريح عبر "close" على ملف إدخال يعيد ضبط عداد الأسطر ($.)، بينما لا يفعل ذلك الإغلاق الضمني الذي تجريه "open".
إذا كان مقبض الملف قادمًا من فتح أنبوبي (piped open)، فستعيد "close" قيمة خطأ إذا فشل أحد نداءات النظام الأخرى المعنية أو إذا خرج برنامجه بحالة غير صفرية. إذا كانت المشكلة الوحيدة هي خروج البرنامج بحالة غير صفرية، فسيُضبط $! على 0. يؤدي إغلاق الأنبوب أيضًا إلى انتظار العملية المنفذة على الأنبوب حتى تخرج -- في حال رغبت في الاطلاع على مخرجات الأنبوب بعد ذلك -- ويضع ضمنيًا قيمة حالة الخروج لذلك الأمر في $? و "${^CHILD_ERROR_NATIVE}".
إذا كانت هناك خيوط (threads) متعددة تعمل، فإن "close" على مقبض ملف من فتح أنبوبي تعيد قيمة صواب دون انتظار انتهاء العملية الابنة، إذا كان مقبض الملف لا يزال مفتوحًا في خيط آخر.
يؤدي إغلاق طرف القراءة للأنبوب قبل أن تنتهي العملية التي تكتب إليه في الطرف الآخر من الكتابة إلى استلام الكاتب إشارة 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 صراحة على المقبض إلى منع ذلك التحذير.
- closedir DIRHANDLE
- تغلق مجلدًا فُتح بواسطة "opendir" وتعيد نجاح نداء النظام ذلك.
- connect SOCKET,NAME
- تحاول الاتصال بمقبس (socket) بعيد، تمامًا مثل connect(2). تعيد قيمة صواب إذا نجحت، وخطأ بخلاف ذلك. يجب أن يكون NAME عنوانًا محزومًا من النوع المناسب للمقبس. انظر الأمثلة في "المقابس: تواصل العميل/الخادم" في perlipc.
- continue BLOCK
- continue
- عندما
تُتبع بـ 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
- cos
- تعيد جيب
التمام (cosine) لـ
EXPR (معبرًا
عنه
بالراديان).
إذا أُغفل
EXPR، تؤخذ جيب
تمام $_.
لعملية جيب التمام العكسية، يمكنك استخدام دالة "Math::Trig::acos"، أو استخدام هذه العلاقة:
sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ) } - crypt PLAINTEXT,SALT
- يُنشئ
سلسلة ملخص
(digest) تماماً
مثل دالة crypt(3)
في مكتبة C
(على افتراض
أن لديك
نسخة هناك
لم تُستأصل
لكونها
ذخيرة
محتملة).
"crypt" هي دالة هاش أحادية الاتجاه. تُحوّل PLAINTEXT (النص الصريح) وSALT (الملح) إلى سلسلة قصيرة تُسمى ملخصاً، وهي القيمة التي تُعاد. سيؤدي استخدام نفس الـ PLAINTEXT والـ SALT دائماً إلى إعادة السلسلة نفسها، ولكن لا توجد طريقة (معروفة) للحصول على الـ PLAINTEXT الأصلي من الهاش. التغييرات الطفيفة في الـ PLAINTEXT أو الـ SALT ستؤدي إلى تغييرات كبيرة في الملخص.
لا توجد دالة لفك التعمية. هذه الدالة ليست مفيدة جداً للأغراض التعموية (لذلك، ابحث عن وحدات Crypt في مرآة CPAN القريبة منك) واسم "crypt" يعد تسمية خاطئة نوعاً ما. بدلاً من ذلك، تُستخدم بشكل رئيس للتحقق مما إذا كان قطعتان من النص متطابقتين دون الحاجة إلى نقل أو تخزين النص نفسه. ومن الأمثلة على ذلك التحقق من صحة كلمة المرور المعطاة. يُخزن ملخص كلمة المرور، وليس كلمة المرور نفسها. يكتب المستخدم كلمة مرور تُعالج بواسطة "crypt" بنفس الملح المستخدم في الملخص المخزن. إذا تطابق الملخصان، تكون كلمة المرور صحيحة.
عند التحقق من سلسلة ملخص موجودة، يجب استخدام الملخص نفسه كملح (مثل "crypt($plain, $digest) eq $digest"). إن الـ SALT المستخدم لإنشاء الملخص يكون مرئياً كجزء من الملخص. يضمن هذا أن "crypt" ستقوم بهاش السلسلة الجديدة بنفس الملح الموجود في الملخص. يسمح هذا لبرمجتك بالعمل مع "crypt" القياسية ومع التطبيقات الأكثر غرابة. وبعبارة أخرى، لا تفترض شيئاً عن السلسلة المعادة نفسها ولا عن عدد بايتات الـ SALT التي قد تكون مهمة.
تقليدياً، النتيجة هي سلسلة من 13 بايتاً: أول بايتين هما الملح، تتبعهما 11 بايتاً من المجموعة "[./0-9A-Za-z]"، وكانت أول ثمانية بايتات فقط من الـ PLAINTEXT هي المهمة. لكن مخططات الهاش البديلة (مثل MD5)، ومخططات الأمان عالية المستوى (مثل C2)، والتطبيقات على المنصات غير التابعة لـ Unix قد تنتج سلاسل مختلفة.
عند اختيار ملح جديد، أنشئ سلسلة عشوائية من حرفين تأتي أحرفها من المجموعة "[./0-9A-Za-z]" (مثل "join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]"). هذه المجموعة من الأحرف هي مجرد توصية؛ فالأحرف المسموح بها في الملح تعتمد كلياً على مكتبة crypt في نظامك، ولا يمكن لـ Perl تقييد الأملاح التي تقبلها دالة "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" غير مناسبة لهاش كميات كبيرة من البيانات، ليس فقط لأنه لا يمكنك استعادة المعلومات. انظر إلى وحدة Digest للحصول على خوارزميات أكثر قوة.
إذا استخدمت "crypt" على سلسلة Unicode (التي يُحتمل أن تحتوي على أحرف بنقاط ترميز فوق 255)، تحاول Perl فهم الموقف بمحاولة خفض رتبة (نسخة من) السلسلة إلى سلسلة بايتات من ثمانية بتات قبل استدعاء "crypt" (على تلك النسخة). إذا نجح ذلك، فبها ونعمت. وإلا، فإن "crypt" تتوقف مع رسالة "Wide character in crypt".
قضايا النقل: "crypt" في perlport.
- dbmclose HASH
- [حلت دالة
"untie" محل
هذه الدالة
بشكل كبير.]
يفك الارتباط بين ملف DBM وهاش.
قضايا النقل: "dbmclose" في perlport.
- dbmopen HASH,DBNAME,MASK
- [حلت دالة
"tie" محل
هذه الدالة
بشكل كبير.]
يربط هذا ملف dbm(3) أو ndbm(3) أو sdbm(3) أو gdbm(3) أو Berkeley DB بهاش. 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
- defined
- تعيد قيمة
منطقية
تخبر ما إذا
كان لـ 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 EXPR
- بإعطاء
تعبير يحدد
عنصراً أو
شريحة من
الهاش،
تقوم
"delete"
بحذف
العناصر
المحددة من
ذلك الهاش
بحيث لا
تعود
"exists" على
ذلك العنصر
تعيد قيمة
صحيحة. ضبط
عنصر هاش
على القيمة
غير
المعرفة لا
يزيل
مفتاحه،
لكن حذفه
يفعل ذلك؛
انظر
"exists".
في سياق القائمة، تعيد عادةً القيمة أو القيم المحذوفة، أو آخر عنصر من هذا القبيل في سياق سلمي. يتوافق طول قائمة الإرجاع مع طول قائمة المعطيات: حذف العناصر غير الموجودة يعيد القيمة غير المعرفة في مواقعها المقابلة. منذ الإصدار 5.28 من Perl، يمكن تمرير شريحة هاش (مفتاح/قيمة) إلى "delete"، وتكون القيمة المعادة قائمة من أزواج مفتاح/قيمة (عنصران لكل بند حُذف من الهاش).
يمكن أيضاً استخدام "delete" على المصفوفات وشرائح المصفوفات، لكن سلوكها أقل وضوحاً. على الرغم من أن "exists" ستعيد قيمة خاطئة للمدخلات المحذوفة، فإن حذف عناصر المصفوفة لا يغير أبداً فهارس القيم الموجودة؛ استخدم "shift" أو "splice" لذلك. ومع ذلك، إذا وقعت أي عناصر محذوفة في نهاية المصفوفة، فإن حجم المصفوفة يتقلص إلى موقع أعلى عنصر لا يزال يختبر كقيمة صحيحة لـ "exists"، أو إلى 0 إذا لم يوجد أي منها. وبعبارة أخرى، لن تحتوي المصفوفة على عناصر زائدة غير موجودة بعد الحذف.
تحذير: لا يُنصح بشدة باستدعاء "delete" على قيم المصفوفة. إن مفهوم حذف أو فحص وجود عناصر مصفوفة Perl ليس متسقاً من الناحية المفاهيمية، ويمكن أن يؤدي إلى سلوك مفاجئ.
الحذف من %ENV يعدل البيئة. الحذف من هاش مربوط بملف DBM يحذف الإدخال من ملف DBM. الحذف من هاش أو مصفوفة "tied" (مربوطة) قد لا يعيد بالضرورة أي شيء؛ يعتمد ذلك على تطبيق طريقة DELETE الخاصة بالحزمة المربوطة، والتي قد تفعل ما تشاء.
تعبير "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 LIST
- تثير "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 إلحاق الموقع أو معلومات أخرى باستثناء مرجعي. إذا كنت تريد معلومات الموقع مع كائن استثناء معقد، سيتعين عليك ترتيب وضع معلومات الموقع في الكائن بنفسك.
لأن $@ هو متغير عام، احذر من أن تحليل استثناء ممسوك بواسطة "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.
- do BLOCK
- ليست دالة
في الواقع.
تعيد قيمة
آخر أمر في
تسلسل
الأوامر
المشار
إليها
بواسطة BLOCK.
عندما
تُعدل
بواسطة
معدل
الحلقة
"while" أو
"until"،
فإنها تنفذ
الـ BLOCK مرة
واحدة قبل
اختبار
حالة
الحلقة. (في
العبارات
الأخرى،
تختبر
معدلات
الحلقة
الشرط
أولاً).
لا تُعتبر "do BLOCK" حلقة، لذا لا يمكن استخدام عبارات التحكم في الحلقة "next"، أو "last"، أو "redo" لمغادرة الكتلة أو إعادة تشغيلها. انظر perlsyn لاستراتيجيات بديلة.
- do EXPR
- تستخدم
قيمة 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
- dump
- تؤدي هذه
الدالة إلى
تفريغ
الذاكرة (core dump)
فوراً. انظر
أيضاً
مفتاح سطر
الأوامر -u
في perlrun، الذي
يفعل الشيء
نفسه. القصد
الرئيس من
ذلك هو أن
تتمكن من
استخدام
برنامج undump
(غير مرفق)
لتحويل
تفريغ
الذاكرة
إلى ملف
ثنائي قابل
للتنفيذ
بعد تهيئة
جميع
متغيراتك
في بداية
البرنامج.
عندما
يُنفذ
الملف
الثنائي
الجديد،
سيبدأ
بتنفيذ
"goto LABEL" (مع
جميع
القيود
التي تعاني
منها
"goto"). فكر
في الأمر
على أنه goto مع
تفريغ
ذاكرة
وتقمص (reincarnation)
متدخلين.
إذا حُذف
الـ "LABEL"،
فسيُعاد
تشغيل
البرنامج
من البداية.
يسمح شكل
"dump EXPR"،
المتاح
بدءاً من
الإصدار 5.18.0
من Perl، بحساب
اسم في وقت
التشغيل،
وهو مطابق
لـ "dump LABEL"
فيما عدا
ذلك.
تحذير: أي ملفات كانت مفتوحة في وقت التفريغ لن تظل مفتوحة عندما يُتقمص البرنامج، مما قد يؤدي إلى ارتباك في Perl.
هذه الدالة أصبحت الآن مهجورة إلى حد كبير، ويرجع ذلك في الغالب إلى صعوبة تحويل ملف تفريغ (core file) إلى ملف قابل للتنفيذ. بدءاً من الإصدار 5.30 من Perl، يجب استدعاؤها بصيغة CORE::dump().
على عكس معظم العوامل المسماة، فإن لهذا العامل نفس أسبقية الإسناد. وهو معفى أيضاً من قاعدة "يبدو وكأنه دالة"، لذا فإن "dump ("foo")."bar"" ستجعل "bar" جزءاً من المعطى لـ "dump".
قضايا النقل: "dump" في perlport.
- each HASH
- each ARRAY
- عند
استدعائها
على هاش في
سياق
قائمة،
فإنها تعيد
قائمة من
عنصرين
تتكون من
المفتاح
والقيمة
للعنصر
التالي في
الهاش. في Perl 5.12
وما بعدها
فقط، ستعيد
أيضاً
الفهرس
والقيمة
للعنصر
التالي في
مصفوفة
بحيث يمكنك
التكرار
عليها؛ أما
في إصدارات
Perl الأقدم
فيُعتبر
هذا خطأ في
الصياغة.
عند
استدعائها
في سياق
سلمي،
فإنها تعيد
المفتاح
فقط (ليس
القيمة) في
الهاش، أو
الفهرس في
المصفوفة.
تُعاد إدخالات الهاش بترتيب يبدو عشوائياً. الترتيب العشوائي الفعلي خاص بهاش معين؛ نفس السلسلة من العمليات على هاشين قد تؤدي إلى ترتيب مختلف لكل منهما. أي إدخال في الهاش قد يغير الترتيب، كما يفعل أي حذف، باستثناء أن المفتاح الأخير الذي أعادته "each" أو "keys" يمكن حذفه دون تغيير الترتيب. طالما لم يُعدل الهاش، يمكنك الاعتماد على "keys" و "values" و "each" لإعادة نفس الترتيب بشكل متكرر كما يفعل بعضهم البعض. انظر "Algorithmic Complexity Attacks" في perlsec للحصول على تفاصيل حول سبب عشوائية ترتيب الهاش. وبصرف النظر عن الضمانات المقدمة هنا، فإن التفاصيل الدقيقة لخوارزمية الهاش وترتيب التنقل فيها تخضع للتغيير في أي إصدار من Perl.
بعد أن تعيد "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" هشة للغاية: فمن السهل الوصول إلى مثل هذه الحلقة والمكرر قد قطع بالفعل جزءاً من الكائن، أو تخريب حالة المكرر عن طريق الخطأ أثناء تنفيذ جسم الحلقة. من السهل جداً إعادة ضبط المكرر صراحةً قبل بدء الحلقة، ولكن لا توجد طريقة لعزل حالة المكرر المستخدمة بواسطة الحلقة عن حالة المكرر المستخدمة بواسطة أي شيء آخر قد يُنفذ أثناء جسم الحلقة. لتجنب هذه المشاكل، استخدم حلقة "foreach" بدلاً من "while"-"each".
يمتد هذا إلى استخدام "each" على نتيجة منشئ هاش أو مصفوفة مجهول. تُنشأ مصفوفة أو هاش أساسي جديد في كل مرة بحيث تبدأ each دائماً التكرار من الصفر، على سبيل المثال:
# loops forever while (my ($key, $value) = each @{ +{ 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 من Perl، يمكنك استخدام "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 ()
- 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" المجردة بلا معطيات هو مجرد "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 لاستثناء.
- Under the "unicode_eval" feature
- إذا مُكنت
هذه الميزة
(وهو
المبدئي
تحت إعلان
"use 5.16" أو
أعلى)،
تفترض بيرل
أن EXPR هي
سلسلة
محارف.
وبذلك لا
يكون لأي
إعلانات
"use utf8" أو
"no utf8"
داخل
السلسلة أي
أثر. كما
تمنع
مرشحات
المصدر
أيضاً. (ومع
ذلك، يمكن
لـ "unicode_strings"
الظهور
داخل
السلسلة).
راجع أيضاً عامل "evalbytes"، الذي يعمل بشكل صحيح مع مرشحات المصدر.
- Outside the "unicode_eval" feature
- في هذه الحالة، يكون السلوك إشكالياً ولا يمكن وصفه بسهولة. إليك خطأين برمجيين لا يمكن إصلاحهما بسهولة دون كسر البرامج الموجودة:
- •
- يؤثر تخزين
بيرل
الداخلي لـ
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" لا ترى النطاق المفرداتي المحيط المعتاد، بل ترى نطاق أول قطعة شيفرة غير تابعة لـ 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
- evalbytes
- هذه الدالة
تشبه تقييم
السلسلة،
إلا أنها
تحلل
معطاها
دائماً (أو
$_ إذا
حُذفت EXPR)
كسلسلة
بايتات. إذا
احتوت
السلسلة
على أي نقاط
ترميز فوق
255، فلا يمكن
أن تكون
سلسلة
بايتات،
وستفشل
"evalbytes" مع
تخزين
الخطأ في
$@.
يكون لـ "use utf8" و "no utf8" داخل السلسلة أثرهما المعتاد.
تنطبق مرشحات المصدر المفعلة داخل الشيفرة المقيمة على الشيفرة نفسها.
تتوفر "evalbytes" بدءاً من الإصدار 5.16 من بيرل. للوصول إليها، يجب كتابة "CORE::evalbytes"، ولكن يمكنك حذف "CORE::" إذا كانت ميزة "evalbytes" مُمكّنة. تُمكّن هذه الميزة آلياً عند استخدام إعلان "use v5.16" (أو أعلى) في النطاق الحالي.
- exec LIST
- exec PROGRAM LIST
- تنفذ دالة
"exec"
أمراً
للنظام
ولا تعود
أبداً؛
استخدم
"system"
بدلاً من
"exec" إذا
كنت تريدها
أن تعود.
وهي تفشل
وتعيد قيمة
خاطئة فقط
إذا كان
الأمر غير
موجود
ونُفذ
مباشرة
بدلاً من
تنفيذه عبر
صدفة أوامر
النظام
(انظر
أدناه).
بما أنه من الخطأ الشائع استخدام "exec" بدلاً من "system"، فإن بيرل تحذرك إذا استُدعيت "exec" في سياق فارغ وإذا كانت تليها جملة ليست "die" أو "warn" أو "exit" (إذا كانت التحذيرات مُمكّنة). إذا كنت تريد حقاً إلحاق "exec" بجملة أخرى، يمكنك استخدام أحد هذه الأنماط لتجنب التحذير:
exec ('foo') أو print STDERR "تعذر exec foo: $!"; { exec ('foo') }; print STDERR "تعذر exec foo: $!";إذا وجد أكثر من معطى واحد في LIST، فإن هذا يستدعي execvp(3) مع المعطيات في LIST. إذا وجد عنصر واحد فقط في LIST، يُفحص المعطى بحثاً عن محارف الصدفة الخاصة، وإذا وُجد أي منها، يُمرر المعطى بالكامل إلى صدفة أوامر النظام لتحليله (هذا هو "/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") يجبر تفسير المعطيات كقائمة متعددة القيم، حتى لو كانت القائمة تحتوي على معطى واحد فقط. بهذه الطريقة تكون في مأمن من قيام الصدفة بتوسيع الرموز العامة أو تقسيم الكلمات التي تحتوي على مسافات بيضاء.
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.
- exists EXPR
- عند
إعطائها
تعبيراً
يحدد
عنصراً في
مفرمة (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];لا يمكن لعنصر مفرمة أو مصفوفة أن يكون صحيحاً إلا إذا كان معرفاً، ولا يكون معرفاً إلا إذا كان موجوداً، ولكن العكس ليس بالضرورة صحيحاً.
عند إعطائها تعبيراً يحدد اسم دالة فرعية، تعيد قيمة صحيحة إذا سبق التصريح عن الدالة الفرعية المحددة، حتى لو كانت غير معرفة. ذكر اسم دالة فرعية من أجل 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 ⊂ # مقبول exists &sub(); # خطأ - exit EXPR
- exit
- تقيم 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
- exp
- تعيد e (أساس اللوغاريتم الطبيعي) مرفوعاً للقوة EXPR. إذا حُذفت EXPR، تعطي exp($_).
- fc EXPR
- fc
- تعيد نسخة
"مطوية
الحالة" (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 FILEHANDLE,FUNCTION,SCALAR
- تطبق دالة
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" في بيرل. هذه السلسلة صحيحة في سياق القيم المنطقية و 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.
- field VARNAME
- يصرح عن متغير حقل جديد داخل الصنف الحالي. سيكون للطرق وكتل "ADJUST" في الصنف وصول إلى هذا المتغير كما لو كان مفرداتياً في النطاق عند تلك النقطة.
- fileno FILEHANDLE
- fileno DIRHANDLE
- تعيد واصف
الملف
لمقبض ملف
أو مقبض
دليل، أو
قيمة غير
معرفة إذا
لم يكن مقبض
الملف
مفتوحاً.
إذا لم يوجد
واصف ملف
حقيقي على
مستوى نظام
التشغيل،
كما يمكن أن
يحدث مع
مقابض
الملفات
المتصلة
بكائنات
ذاكرة عبر
"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 FILEHANDLE,OPERATION
- تستدعي flock(2)،
أو محاكاة
لها، على FILEHANDLE.
تعيد قيمة
صحيحة
للنجاح،
وخاطئة
للفشل.
تُنتج خطأً
قاتلاً إذا
استُخدمت
على آلة لا
تطبق قفل flock(2)
أو fcntl(2) أو lockf(3).
تُعد "flock"
واجهة قفل
الملفات
النقولة في
بيرل، رغم
أنها تقفل
الملفات
بالكامل
فقط، وليس
السجلات.
هناك دلالتان تقليديتان لـ "flock" قد لا تكونان واضحتين وهما أنها تنتظر إلى ما لا نهاية حتى يُمنح القفل، وأن أقفالها استشارية فقط. هذه الأقفال التقديرية أكثر مرونة، ولكنها تقدم ضمانات أقل. هذا يعني أن البرامج التي لا تستخدم أيضاً "flock" قد تعدل الملفات المقفولة بـ "flock". راجع perlport ووثائق المنصة الخاصة بك وصفحات الدليل المحلية للحصول على التفاصيل. من الأفضل افتراض السلوك التقليدي إذا كنت تكتب برامج نقولة. (ولكن إذا لم تكن كذلك، فيجب عليك كالعادة أن تشعر بحرية تامة في الكتابة لخصائص نظامك الخاصة (والتي تُسمى أحياناً "ميزات")). لا ينبغي للالتزام العبودي بمخاوف النقلية أن يعيقك عن إنجاز عملك.
العملية (OPERATION) هي واحدة من LOCK_SH أو LOCK_EX أو LOCK_UN، وربما تُدمج مع LOCK_NB. هذه الثوابت تأخذ تقليدياً القيم 1 و 2 و 8 و 4، ولكن يمكنك استخدام الأسماء الرمزية إذا استوردتها من وحدة Fcntl، إما بشكل فردي أو كمجموعة باستخدام وسم ":flock". يطلب LOCK_SH قفلاً مشتركاً، ويطلب LOCK_EX قفلاً حصرياً، ويقوم LOCK_UN بتحرير قفل طُلب سابقاً. إذا دُمج 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 لمزيد من الأمثلة حول التفريع وحصد العمليات الابنة المحتضرة.
لاحظ أنه إذا ورث ابنك المفرع واصفات ملفات النظام مثل 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 للحصول على العديد من التفاصيل والأمثلة.
- formline PICTURE,LIST
- هذه دالة
داخلية
تستخدمها
التنسيقات
(formats)، رغم أنه
يمكنك
استدعاؤها
أيضاً. تقوم
بتنسيق
(انظر perlform)
قائمة من
القيم
وفقاً
لمحتويات
PICTURE، وتضع
المخرجات
في مركم
مخرجات
التنسيق،
$^A (أو
$ACCUMULATOR
بالإنجليزية).
في
النهاية،
عند إجراء
"write"،
تُكتب
محتويات
$^A إلى
مقبض ملف
ما. يمكنك
أيضاً
قراءة $^A
ثم إعادة
ضبط $^A
إلى "".
لاحظ أن
التنسيق
عادةً ما
ينفذ
"formline"
واحدة لكل
سطر من
النموذج،
لكن دالة
"formline"
نفسها لا
تهتم بعدد
الأسطر
الجديدة
المضمنة في
PICTURE. وهذا يعني
أن علامات
"~" و
"~~"
تعامل PICTURE
بأكملها
كسطر واحد.
لذلك قد
تحتاج إلى
استخدام
عدة formlines
لتنفيذ
تنسيق سجل
واحد،
تماماً مثل
مصرف
"format".
كن حذراً إذا وضعت علامتي اقتباس مزدوجتين حول الصورة، لأن حرف "@" قد يُفهم على أنه بداية اسم مصفوفة. تعيد "formline" دائماً قيمة صحيحة. انظر perlform لمزيد من الأمثلة.
إذا كنت تحاول استخدام هذه الدالة بدلاً من "write" لالتقاط المخرجات، فقد تجد أنه من الأسهل فتح مقبض ملف إلى كمية سلمية ("open my $fh, ">", \$output") والكتابة إليها بدلاً من ذلك.
- getc FILEHANDLE
- getc
- تُعيد
المحرف
التالي من
ملف
الإدخال
المرفق بـ
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.
- getlogin
- تنفذ هذه
الدالة
دالة مكتبة
C التي تحمل
الاسم
نفسه،
والتي
تُعيد في
معظم
الأنظمة
اسم الولوج
الحالي من
/etc/utmp إن وجد.
إذا أعادت
سلسلة
فارغة،
فاستخدم
"getpwuid".
my $login = getlogin || getpwuid($<) || "Kilroy";لا تعتمد على "getlogin" للاستيثاق: فهي ليست آمنة مثل "getpwuid".
مسائل القابلية للنقل: "getlogin" في perlport.
- getpeername SOCKET
- تُعيد
عنوان 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); - getpgrp PID
- تُعيد
مجموعة
العمليات
الحالية لـ
PID المحدد.
استخدم PID
بقيمة 0
للحصول على
مجموعة
العمليات
الحالية
للعملية
الحالية.
ستثير
استثناءً
إذا
استُخدمت
على جهاز لا
ينفذ getpgrp(2).
إذا حُذف PID،
تُعيد
مجموعة
العمليات
للعملية
الحالية.
بعض الأجهزة القديمة جداً قد لا تدعم "PID != 0" وسترمي استثناءً إذا كانت "PID != 0".
مسائل القابلية للنقل: "getpgrp" في perlport.
- getppid
- تُعيد معرف
العملية (PID)
لعملية
الأب.
ملاحظة لمستخدمي لينكس: بين الإصدارين v5.8.1 و v5.16.0 كانت بيرل تعالج دلالات خيوط المعالجة غير المتوافقة مع POSIX في أقلية من أنظمة لينكس (وأنظمة Debian GNU/kFreeBSD) التي استخدمت LinuxThreads، وقد أُزيلت هذه المحاكاة منذ ذلك الحين. انظر توثيق $$ للمزيد من التفاصيل.
مسائل القابلية للنقل: "getppid" في perlport.
- getpriority WHICH,WHO
- تُعيد
الأولوية
الحالية
لعملية، أو
مجموعة
عمليات، أو
مستخدم.
(انظر getpriority(2).)
ستثير
استثناءً
قاتلاً إذا
استُخدمت
على جهاز لا
ينفذ getpriority(2).
يمكن أن تكون "WHICH" أي واحدة من "PRIO_PROCESS"، أو "PRIO_PGRP"، أو "PRIO_USER" المستوردة من "RESOURCE CONSTANTS" في POSIX.
مسائل القابلية للنقل: "getpriority" في perlport.
- getpwnam NAME
- getgrnam NAME
- gethostbyname NAME
- getnetbyname NAME
- getprotobyname NAME
- getpwuid UID
- getgrgid GID
- getservbyname NAME,PROTO
- gethostbyaddr ADDR,ADDRTYPE
- getnetbyaddr ADDR,ADDRTYPE
- getprotobynumber NUMBER
- getservbyport PORT,PROTO
- getpwent
- getgrent
- gethostent
- getnetent
- getprotoent
- getservent
- setpwent
- setgrent
- sethostent STAYOPEN
- setnetent STAYOPEN
- setprotoent STAYOPEN
- setservent STAYOPEN
- endpwent
- endgrent
- endhostent
- endnetent
- endprotoent
- endservent
- هذه
الروتينات
هي نفسها
نظيراتها
في مكتبة
النظام 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(إذا لم يكن الإدخال موجوداً، فإن قيمة الإرجاع هي قيمة وحيدة صحيحة لا معنى لها.)
يختلف المعنى الدقيق لحقل $gcos ولكنه يحتوي عادةً على الاسم الحقيقي للمستخدم (على عكس اسم الولوج) ومعلومات أخرى تتعلق بالمستخدم. احذر، مع ذلك، من أنه في العديد من الأنظمة يستطيع المستخدمون تغيير هذه المعلومات، وبالتالي لا يمكن الوثوق بها، ومن ثم يكون الحقل $gcos ملوثاً (tainted) (انظر perlsec). كما أن $passwd و $shell، وهما كلمة مرور المستخدم المشفرة وصدفة الولوج، ملوثان أيضاً للسبب نفسه.
في السياق السلمي (scalar context)، تحصل على الاسم، ما لم تكن الدالة بحثاً بالاسم، وفي هذه الحالة تحصل على الشيء الآخر، أياً كان. (إذا لم يكن الإدخال موجوداً، تحصل على القيمة غير المعرفة). على سبيل المثال:
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 من داخل Perl باستخدام وحدة "Config" والقيم "d_pwquota" و "d_pwage" و "d_pwchange" و "d_pwcomment" و "d_pwexpire". ملفات كلمات المرور الظلية (Shadow password) مدعومة فقط إذا كان المورد قد نفذها بالطريقة البديهية بحيث أن استدعاء روتينات مكتبة C العادية يجلب إصدارات الظل إذا كنت تعمل تحت امتياز أو إذا وجدت دوال shadow(3) كما هو موجود في System V (وهذا يشمل Solaris و Linux). الأنظمة التي تنفذ مرفق كلمة مرور ظلية مملوكًا من غير المرجح أن تكون مدعومة.
قيمة $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.
- getsockname SOCKET
- تُعيد
عنوان 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); - getsockopt SOCKET,LEVEL,OPTNAME
- تستعلم عن
الخيار
المسمى OPTNAME
المرتبط
بالمقبس SOCKET
عند مستوى LEVEL
معين. قد
توجد
الخيارات
عند
مستويات
بروتوكول
متعددة
اعتماداً
على نوع
المقبس،
لكن على
الأقل
سيوجد أعلى
مستوى
للمقبس SOL_SOCKET
(المُعرف في
وحدة
"Socket").
للاستعلام
عن خيارات
عند مستوى
آخر، يجب
توفير رقم
البروتوكول
للبروتوكول
المناسب
الذي يتحكم
في الخيار.
على سبيل
المثال،
للإشارة
إلى أن
خياراً ما
سيُفسر
بواسطة
بروتوكول
TCP، يجب ضبط LEVEL
على رقم
بروتوكول
TCP، والذي
يمكنك
الحصول
عليه
باستخدام
"getprotobyname".
تُعيد الدالة سلسلة مجمعة (packed string) تمثل خيار المقبس المطلوب، أو "undef" عند حدوث خطأ، مع وضع سبب الخطأ في $!. ما يوجد بالضبط في السلسلة المجمعة يعتمد على LEVEL و OPTNAME؛ ارجع إلى getsockopt(2) للتفاصيل. الحالة الشائعة هي أن يكون الخيار عدداً صحيحاً، وفي هذه الحالة تكون النتيجة عدداً صحيحاً مجمعاً، يمكنك فك ترميزه باستخدام "unpack" مع التنسيق "i" (أو "I").
إليك مثال لاختبار ما إذا كانت خوارزمية Nagle مفعلة على مقبس:
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
- glob
- في سياق
القائمة،
تُعيد
قائمة (قد
تكون فارغة)
من توسعات
أسماء
الملفات
بناءً على
قيمة 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(".* *")" جميع الملفات في دليل العمل الحالي. إذا كنت تريد مطابقة أسماء ملفات قد تحتوي على مساحات بيضاء، فسيتعين عليك استخدام علامات اقتباس إضافية حول اسم الملف الذي يحتوي على مسافات لحمايته. على سبيل المثال، لمطابقة أسماء الملفات التي تحتوي على حرف "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
- gmtime
- تعمل
تماماً مثل
"localtime"،
ولكن القيم
المعادة
تكون محلية
وفقاً
لتوقيت
غرينتش
القياسي.
ملاحظة: عند الاستدعاء في سياق القائمة، تكون $isdst، وهي القيمة الأخيرة التي تعيدها gmtime، دائماً 0. فلا يوجد توقيت صيفي في GMT.
مسائل القابلية للنقل: "gmtime" في perlport.
- goto LABEL
- goto EXPR
- goto &NAME
- تبحث صيغة
"goto LABEL" عن
العبارة
الموسومة
بـ LABEL
وتستأنف
التنفيذ
هناك. لا
يمكن
استخدامها
للخروج من
كتلة
برمجية (block) أو
روتين فرعي
ممرر لـ
"sort". يمكن
استخدامها
للانتقال
إلى أي مكان
آخر
تقريباً
ضمن النطاق
الديناميكي،
بما في ذلك
الخروج من
الروتينات
الفرعية،
ولكن من
الأفضل
عادةً
استخدام
بنية أخرى
مثل "last"
أو "die". لم
يشعر مؤلف
بيرل أبداً
بالحاجة
إلى
استخدام
هذه الصيغة
من "goto"
(في بيرل
تحديداً؛
أما في C
فالأمر
مختلف).
(الفرق هو
أن C لا توفر
حلقات
مسماة
مقترنة
بالتحكم في
الحلقة،
بينما تفعل
بيرل ذلك،
وهذا يحل
محل معظم
الاستخدامات
المهيكلة
لـ "goto" في
اللغات
الأخرى).
تتوقع الصيغة "goto EXPR" تقييم "EXPR" إلى مرجع برمجي أو اسم لصيقة. إذا قُيّم إلى مرجع برمجي، فسيُعامل مثل "goto &NAME" المذكورة أدناه. يفيد هذا خصوصًا في تنفيذ العودية الذيلية (tail recursion) عبر "goto __SUB__".
إذا قُيّم التعبير إلى اسم لصيقة، فسيُحل نطاقه ديناميكيًا. يسمح هذا بعمليات "goto" محسوبة وفق أسلوب فورتران (FORTRAN)، لكن لا يُنصح به بالضرورة إذا كنت تسعى لتحسين قابلية الصيانة:
goto ("FOO", "BAR", "GLARCH")[$i];كما يظهر في هذا المثال، تُعفى "goto EXPR" من قاعدة "ما يبدو دالة". فلا يحدد زوج الأقواس الذي يليها وسيطها (بالضرورة). فالتعبير "goto("NE")."XT"" يكافئ "goto NEXT". كما أن لهذا العامل، بخلاف معظم العوامل المسماة، أسبقية الإسناد نفسها.
يعد استخدام "goto LABEL" أو "goto EXPR" للقفز إلى داخل بنية ما مهجورًا وسيصدر تحذيرًا؛ وسيصبح خطأً فادحًا في إصدار بيرل 5.42. وبينما لا يزال متاحًا، فلا يجوز استخدامه للدخول إلى أي بنية تتطلب تهيئة، مثل دالة فرعية، أو حلقة "foreach"، أو كتلة "given". وبوجه عام، لا يجوز استخدامه للقفز إلى معامل لعامل ثنائي أو عامل قائمة، ولكن يمكن استخدامه للقفز إلى المعامل الأول لعامل ثنائي. (المعامل "الأول" لعامل الإسناد "=" هو معامله الأيمن). كما لا يمكن استخدامه للدخول في بنية أُزيلت عبر التحسين.
تختلف الصيغة "goto &NAME" تمامًا عن الصيغ الأخرى لـ "goto". في الواقع، هي ليست goto بالمعنى المعتاد على الإطلاق، ولا تحمل السمعة السيئة المرتبطة بعمليات goto الأخرى. بدلاً من ذلك، فإنها تخرج من الدالة الفرعية الحالية (وتفقد أي تغييرات عُينت بواسطة "local") وتستدعي فورًا مكانها الدالة الفرعية المسماة باستخدام القيمة الحالية لـ @_. يُستخدم هذا بواسطة دوال "AUTOLOAD" التي ترغب في تحميل دالة فرعية أخرى ثم التظاهر بأن الدالة الأخرى هي التي استُدعيت في المقام الأول (باستثناء أن أي تعديلات على @_ في الدالة الحالية تُنقل إلى الدالة الأخرى). بعد "goto"، لن يتمكن حتى "caller" (المستدعِي) من معرفة أن هذه الدالة كانت المستدعاة أولاً.
ليس بالضرورة أن يكون NAME اسمًا لدالة فرعية؛ بل يمكن أن يكون متغيرًا سلميًا يحتوي على مرجع برمجي أو كتلة تُقيّم إلى مرجع برمجي.
- grep BLOCK LIST
- grep EXPR,LIST
- هذا مشابه
في جوهره
لبرنامج grep(1)
وأقاربه،
ولكنه ليس
نفسه. على
وجه
الخصوص، هو
غير مقتصر
على
استخدام
التعبيرات
النمطية.
يُقيّم BLOCK أو EXPR لكل عنصر من عناصر LIST (مع تعيين $_ محليًا لكل عنصر) ويعيد قيمة القائمة المكونة من تلك العناصر التي قُيّم التعبير لها بأنه صواب. في السياق السلمي، يعيد عدد المرات التي كان فيها التعبير صوابًا.
my @foo = grep(!/^#/, @bar); # استبعاد التعليقاتأو بشكل مكافئ،
my @foo = grep {!/^#/} @bar; # استبعاد التعليقاتلاحظ أن $_ هو اسم مستعار لقيمة القائمة، لذا يمكن استخدامه لتعديل عناصر LIST. وبينما يعد هذا مفيدًا ومدعومًا، إلا أنه قد يسبب نتائج غريبة إذا لم تكن عناصر LIST متغيرات. وبالمثل، يعيد grep أسماءً مستعارة تشير إلى القائمة الأصلية، تمامًا مثلما يشير متغير الفهرس في حلقة for إلى عناصر القائمة. أي أن تعديل عنصر في قائمة أعادها grep (على سبيل المثال، في "foreach" أو "map" أو "grep" أخرى) سيؤدي فعليًا إلى تعديل العنصر في القائمة الأصلية. وعادة ما يكون هذا شيئًا يجب تجنبه عند كتابة كود واضح.
انظر أيضًا "map" للحصول على قائمة مؤلفة من نتائج BLOCK أو EXPR.
- hex EXPR
- hex
- يفسر 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 LIST
- لا توجد دالة "import" مبنية مسبقًا. إنها مجرد طريقة (دالة فرعية) عادية تُعرف (أو تُورث) بواسطة الوحدات التي ترغب في تصدير أسماء إلى وحدة أخرى. تستدعي دالة "use" طريقة "import" للحزمة المستخدمة. انظر أيضًا "use" و perlmod و Exporter.
- index STR,SUBSTR,POSITION
- index STR,SUBSTR
- تبحث دالة 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
- int
- يعيد الجزء الصحيح من EXPR. إذا حُذف EXPR، يُستخدم $_. لا ينبغي استخدام هذه الدالة للتقريب: أولاً لأنها تقتطع باتجاه 0، وثانيًا لأن التمثيلات الآلية للأرقام ذات الفاصلة العائمة قد تنتج أحيانًا نتائج غير متوقعة. على سبيل المثال، ينتج int(-6.725/0.025) القيمة -268 بدلاً من -269 الصحيحة؛ وذلك لأنها في الواقع أقرب إلى -268.99999999999994315658. عادةً ما تكون الدوال "sprintf" و "printf" أو دوال "POSIX::floor" و "POSIX::ceil" أفضل لك من "int".
- ioctl FILEHANDLE,FUNCTION,SCALAR
- تنفذ دالة
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.
- join EXPR,LIST
- يضم
السلاسل
المنفصلة
في LIST في
سلسلة نصية
واحدة مع
فصل الحقول
بقيمة EXPR،
ويعيد تلك
السلسلة
الجديدة.
مثال:
my $rec = join(':', $login,$passwd,$uid,$gid,$gcos,$home,$shell);احذر من أن "join"، على عكس "split"، لا تأخذ نمطًا كوسيط أول لها. قارن مع "split".
- keys HASH
- keys ARRAY
- عند
استدعائها
في سياق
قائمة،
تعيد قائمة
تتكون من
جميع
مفاتيح
الهاش
المسمى، أو
في إصدار
بيرل 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)، تسمح لك "keys" بزيادة عدد دلاء الهاش (hash buckets) المخصصة لهاش معين. يمكن أن يمنحك هذا قدرًا من الكفاءة إذا كنت تعلم أن الهاش سيصبح كبيرًا. (هذا مشابه لتوسيع المصفوفة مسبقًا عن طريق تعيين رقم أكبر لـ $#array). إذا كتبت
keys %hash = 200;فسيتم تخصيص 200 دلو على الأقل لـ %hash، وفي الواقع 256 منها، حيث يُقرب العدد إلى القوة التالية للرقم اثنين. سيُحتفظ بهذه الدلاء حتى لو أجريت "%hash = ()"؛ استخدم undef %hash إذا كنت تريد تحرير مساحة التخزين بينما لا يزال %hash في النطاق. لا يمكنك تقليص عدد الدلاء المخصصة للهاش باستخدام "keys" بهذه الطريقة (لكن لا داعي للقلق بشأن القيام بذلك عن طريق الخطأ، لأن المحاولة ليس لها أي تأثير). استخدام "keys @array" في سياق قيمة يسارية يعد خطأً في الصيغة.
بدءًا من إصدار بيرل 5.14، سمحت ميزة تجريبية لـ "keys" بأخذ تعبير سلمي. عُدّت هذه التجربة غير ناجحة، وأُزيلت اعتبارًا من بيرل 5.24.
لتجنب إرباك المستخدمين المحتملين لكودك الذين يشغلون إصدارات أقدم من Perl بأخطاء صياغة غامضة، ضع هذا النوع من الأشياء في أعلى ملفك للإشارة إلى أن كودك سيعمل فقط على إصدارات Perl الحديثة:
use v5.12; # لكي تعمل keys/values/each على المصفوفاتانظر أيضًا "each" و "values" و "sort".
- kill SIGNAL, LIST
- kill SIGNAL
- يرسل إشارة
إلى قائمة
من
العمليات.
يعيد عدد
الوسائط
التي
استُخدمت
بنجاح
لإرسال
الإشارة
(وهو ليس
بالضرورة
عدد
العمليات
التي قُتلت
فعليًا،
على سبيل
المثال عند
قتل مجموعة
عمليات).
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" مما إذا كان من الممكن إرسال إشارة إليها (وهذا يعني باختصار أن العملية مملوكة للمستخدم نفسه، أو أننا المستخدم الخارق). هذا مفيد للتحقق من أن العملية الابنة لا تزال حية (حتى لو كانت مجرد عملية زومبي) ولم تغير معرف المستخدم (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
- يشبه أمر
"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
- lc
- يعيد نسخة
مصغرة
الأحرف (lowercased)
من EXPR. إذا
حُذف EXPR،
يُستخدم
$_.
my $str = lc("Perl is GREAT"); # "perl is great"تعتمد القيمة المعادة على عدة عوامل:
- If "use bytes" is in effect:
- تتبع النتائج قواعد ASCII. تتغير الأحرف "A-Z" فقط إلى "a-z" على التوالي.
- Otherwise, if "use locale" for "LC_CTYPE" is in effect:
- تحترم
محلية
"LC_CTYPE"
الحالية
لنقاط
الكود < 256؛
وتستخدم
قواعد
يونيكود (Unicode)
لنقاط
الكود
المتبقية
(لا يمكن أن
يحدث هذا
الأخير إلا
إذا كانت
علامة UTF8
معدة
أيضًا).
انظر perllocale.
بدءًا من الإصدار v5.20، يستخدم بيرل قواعد يونيكود الكاملة إذا كانت المحلية 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 في المحلية الحالية، وليس لدى بيرل طريقة لمعرفة ما إذا كان هذا الحرف موجودًا أصلاً في المحلية، فضلاً عن نقطة الكود الخاصة به. يعيد بيرل نتيجة أعلى من 255 (دائمًا ما يكون حرف الإدخال دون تغيير)، لجميع الحالات (وهي ليست كثيرة) التي قد يتم فيها تجاوز الحد الفاصل 255/256؛ وبدءًا من v5.22، فإنه يصدر تحذير محلية.
- وإلا، إذا كانت علامة UTF8 معدة لـ EXPR:
- تُستخدم قواعد يونيكود لتغيير حالة الأحرف.
- Otherwise, if "use feature 'unicode_strings'" or "use locale ':not_characters'" is in effect:
- تُستخدم قواعد يونيكود لتغيير حالة الأحرف.
- وإلا:
- تُستخدم قواعد ASCII لتغيير حالة الأحرف. حالة الأحرف الصغيرة لأي حرف خارج نطاق ASCII هي الحرف نفسه.
ملاحظة: هذه هي الدالة الداخلية التي تنفذ هروب "\L" في السلاسل النصية المحاطة بعلامات اقتباس مزدوجة.
my $str = "Perl is \LGREAT\E"; # "Perl is great"
- lcfirst EXPR
- lcfirst
- يعيد قيمة EXPR
مع تحويل
الحرف
الأول إلى
حالة
الأحرف
الصغيرة.
هذه هي
الدالة
الداخلية
التي تنفذ
هروب "\l"
في السلاسل
النصية
المحاطة
بعلامات
اقتباس
مزدوجة.
إذا حُذفت EXPR، تُستخدم $_.
تتصرف هذه الدالة بالطريقة نفسها التي تتصرف بها "lc" تحت مختلف البرغما (pragmas)، كما هو الحال في المحلية.
- length EXPR
- length
- يعيد الطول
بـ الأحرف
لقيمة EXPR. إذا
حُذف EXPR،
يعيد طول
$_. إذا
كان EXPR غير
محدد، يعيد
"undef".
لا يمكن استخدام هذه الدالة على مصفوفة كاملة أو هاش لمعرفة عدد العناصر التي تحتوي عليها. لذلك، استخدم "scalar @array" و scalar keys %hash، على التوالي.
مثل جميع عمليات الأحرف في بيرل، تتعامل "length" عادةً بالأحرف المنطقية، وليس بالبايتات المادية. لمعرفة عدد البايتات التي ستشغلها سلسلة نصية مرمزة بـ UTF-8، استخدم "length(Encode::encode('UTF-8', EXPR))" (سيتعين عليك كتابة "use Encode" أولاً). انظر Encode و perlunicode.
- __LINE__
- علامة (token) خاصة تترجم إلى رقم السطر الحالي. يمكن تغييرها بواسطة الآلية الموضحة في "Plain Old Comments (Not!)" في perlsyn.
- link OLDFILE,NEWFILE
- ينشئ اسم
ملف جديدًا
مرتبطًا
باسم الملف
القديم.
يعيد
صوابًا عند
النجاح،
وخطأً خلاف
ذلك.
قضايا القابلية للنقل: "link" في perlport.
- listen SOCKET,QUEUESIZE
- يقوم بالشيء نفسه الذي يقوم به استدعاء النظام listen(2). يعيد صوابًا إذا نجح، وخطأً خلاف ذلك. انظر المثال في "Sockets: Client/Server Communication" في perlipc.
- local EXPR
- ربما ترغب
حقًا في
استخدام
"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
- localtime
- تُحوّل
الوقت
المُعطى من
دالة time إلى
قائمة
مكونة من 9
عناصر مع
تحليل
الوقت
للمنطقة
الزمنية
المحلية.
تُستخدم
عادةً كما
يلي:
# 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 هو يوم الشهر، و $mon هو الشهر في النطاق 0..11، حيث يشير 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. للحصول على السنة الكاملة اكتب:
$year += 1900;للحصول على آخر رقمين من السنة (مثلاً، "01" في 2001) افعل الآتي:
$year = sprintf("%02d", $year % 100);$wday هو يوم الأسبوع، حيث يشير 0 إلى الأحد و 3 إلى الأربعاء. $yday هو يوم السنة، في النطاق 0..364 (أو 0..365 في السنوات الكبيسة).
تكون $isdst صحيحة (true) إذا كان الوقت المحدد يقع ضمن وقت التوقيت الصيفي المعمول به، وخاطئة (false) خلاف ذلك.
إذا حُذف EXPR، تستخدم "localtime" الوقت الحالي (كما تُعيده دالة "time").
في سياق عددي، تُعيد "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.
- lock THING
- تضع هذه
الدالة
قفلاً
استشارياً
على متغير
مشترك أو
كائن مُشار
إليه موجود
في THING حتى
يخرج القفل
عن النطاق.
القيمة المُعادة هي المتغير العددي نفسه إذا كان المعامل عددي، أو مرجع (reference) إذا كان المعامل جدول تجزئة أو مصفوفة أو روتين فرعي.
"lock" هي "كلمة مفتاحية ضعيفة"؛ وهذا يعني أنه إذا كنت قد عرفت دالة بهذا الاسم (قبل أي استدعاء لها)، فسيتم استدعاء تلك الدالة بدلاً منها. إذا لم تكن تحت "use threads::shared" فلن تفعل شيئاً. انظر threads::shared.
- log EXPR
- log
- تُعيد
اللوغاريتم
الطبيعي
(الأساس e)
لـ EXPR. إذا
حُذف EXPR،
تُعيد
لوغاريتم
$_.
للحصول على
لوغاريتم
لأساس آخر،
استخدم
الجبر
الأساسي:
لوغاريتم
عدد للأساس
N يساوي
اللوغاريتم
الطبيعي
لذلك العدد
مقسوماً
على
اللوغاريتم
الطبيعي لـ
N. على سبيل
المثال:
sub log10 { my $n = shift; return log($n)/log(10); }انظر أيضاً "exp" للعملية العكسية.
- lstat FILEHANDLE
- lstat EXPR
- lstat DIRHANDLE
- lstat
- تفعل نفس ما
تفعله دالة
"stat" (بما
في ذلك ضبط
واصف الملف
الخاص
"_")
لكنها تجلب
معلومات
الرابط
الرمزي
بدلاً من
الملف الذي
يشير إليه
الرابط
الرمزي. إذا
كانت
الروابط
الرمزية
غير مفعلة
في نظامك،
فسيتم
إجراء
"stat" عادي.
لمعلومات
أكثر
تفصيلاً،
يرجى
مراجعة
توثيق
"stat".
إذا حُذف EXPR، يتم جلب معلومات $_.
قضايا قابلية النقل: "lstat" في perlport.
- m//
- عامل المطابقة. انظر "Regexp Quote-Like Operators" في perlop.
- map BLOCK LIST
- map EXPR,LIST
- تُقيم
الكتلة (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للحصول على قائمة من جداول التجزئة المجهولة، لكل منها مدخل واحد فقط.
- method NAME BLOCK
- method NAME : ATTRS BLOCK
- تنشئ دالة جديدة مسماة في نطاق الفئة (class) التي تظهر فيها. هذا صالح فقط داخل تصريح "class".
- mkdir FILENAME,MODE
- mkdir FILENAME
- mkdir
- تنشئ
المجلد
المحدد
بواسطة 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.
- msgctl ID,CMD,ARG
- تستدعي
دالة 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.
- msgget KEY,FLAGS
- تستدعي
دالة System V IPC
المسماة msgget(2).
تُعيد معرف
طابور
الرسائل،
أو "undef"
عند حدوث
خطأ. انظر
أيضاً "SysV IPC"
في perlipc وتوثيق
"IPC::SysV" و
"IPC::Msg".
قضايا قابلية النقل: "msgget" في perlport.
- msgrcv ID,VAR,SIZE,TYPE,FLAGS
- تستدعي
دالة System V IPC
المسماة msgrcv
لاستلام
رسالة من
معرف طابور
الرسائل ID
إلى
المتغير VAR
بحد أقصى
لحجم
الرسالة هو
SIZE. لاحظ أنه
عند استلام
رسالة،
سيكون نوع
الرسالة
كعدد صحيح
طويل أصلي
هو أول شيء
في VAR، يتبعه
الرسالة
الفعلية.
يمكن فتح
هذا الحزم
باستخدام
"unpack("l! a*")".
تلوث
المتغير.
تُعيد قيمة
صحيحة إذا
نجحت،
وخاطئة عند
حدوث خطأ.
انظر أيضاً
"SysV IPC" في perlipc
وتوثيق
"IPC::SysV" و
"IPC::Msg".
قضايا قابلية النقل: "msgrcv" في perlport.
- msgsnd ID,MSG,FLAGS
- تستدعي
دالة System V IPC
المسماة msgsnd
لإرسال
الرسالة MSG
إلى طابور
الرسائل ذي
المعرف ID.
يجب أن تبدأ
MSG بنوع
الرسالة
كعدد صحيح
طويل أصلي،
يتبعه
الرسالة
نفسها. يمكن
تحقيق هذا
النوع من
الحزم
باستخدام
"pack("l! a*", $type,
$message)". تُعيد
قيمة صحيحة
إذا نجحت،
وخاطئة عند
حدوث خطأ.
انظر أيضاً
"SysV IPC" في perlipc
وتوثيق
"IPC::SysV" و
"IPC::Msg".
قضايا قابلية النقل: "msgsnd" في perlport.
- my VARLIST
- my TYPE VARLIST
- my VARLIST : ATTRS
- my TYPE VARLIST : ATTRS
- تُصرح
"my" بأن
المتغيرات
المدرجة
محلية
(معجمياً)
للكتلة
المحيطة،
أو الملف،
أو "eval".
إذا أُدرج
أكثر من
متغير
واحد، يجب
وضع
القائمة
بين قوسين.
لاحظ أنه مع القائمة الموضوعة بين قوسين، يمكن استخدام "undef" كعنصر نائب وهمي، على سبيل المثال لتخطي إسناد القيم الأولية:
my ( undef, $min, $hour ) = localtime;مثل "state" و "local" و "our"، يمكن لـ "my" العمل على متغير في أي مكان يظهر فيه في تعبير (باستثناء الإقحام داخل السلاسل النصية). لن ينطبق التصريح على الاستخدامات الإضافية لنفس المتغير حتى البيان (statement) التالي. هذا يعني أن الاستخدامات الإضافية لهذا المتغير داخل نفس البيان ستعمل كما كانت قبل حدوث ذلك التصريح، أو ستؤدي إلى خطأ 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
- أمر "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".
- no MODULE VERSION LIST
- no MODULE VERSION
- no MODULE LIST
- no MODULE
- no VERSION
- انظر دالة "use"، والتي تُعد "no" عكسها.
- oct EXPR
- oct
- تفسر 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" فقط مع الأعداد الصحيحة غير السالبة، وليس الأعداد الصحيحة السالبة أو الأعداد العشرية).
- open FILEHANDLE,MODE,EXPR
- open FILEHANDLE,MODE,EXPR,LIST
- open FILEHANDLE,MODE,REFERENCE
- open FILEHANDLE,EXPR
- open FILEHANDLE
- تربط واصف
ملف (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" ضرورية عندما لا تعمل مع ملف نصي. من أجل قابلية النقل، من الجيد استخدامها دائمًا عندما يكون ذلك مناسبًا، وعدم استخدامها مطلقًا عندما لا يكون مناسبًا. أيضًا، يمكن للمستخدمين ضبط الإدخال/الإخراج الخاص بهم ليكون مبدئيًا بترميز Unicode بتنسيق UTF8، وليس بايتات.
- Using "undef" for temporary files
- كحالة
خاصة، صيغة
المعاملات
الثلاثة مع
نمط
قراءة/كتابة
ويكون
المعامل
الثالث هو
"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) ولا تريد الاضطرار إلى فحص أوامر الصدفة بحثًا عن محارف فوقية (metacharacters).
الكتل التالية متكافئة تقريبًا:
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 مكتبة C القياسية fdopen(3) لتنفيذ وظيفة "=". في العديد من أنظمة 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_filehandles". تُعطل هذه الميزة آليًا عندما تكون في نطاق "use v5.36.0" أو أحدث.
- Calling "open" with one argument via global variables
- كاختصار،
يأخذ
استدعاء
المعامل
الواحد اسم
الملف من
المتغير
السلمي
العام الذي
له نفس اسم
مقبض الملف
ذو الكلمة
المجردة:
$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 )"، الذي ينتج اسم ملف يمكن فتحه بشكل طبيعي.)
- Invoking C-style "open"
- إذا كنت
تريد 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.
- opendir DIRHANDLE,EXPR
- يفتح
دليلًا
باسم EXPR
لمعالجته
بواسطة
"readdir"، و
"telldir"، و
"seekdir"، و
"rewinddir"، و
"closedir".
يعيد
صحيحًا إذا
كان ناجحًا.
قد يكون DIRHANDLE
تعبيرًا
يمكن
استخدام
قيمته
كمقبض دليل
غير مباشر،
عادةً ما
يكون اسم
مقبض
الدليل
الحقيقي.
إذا كان DIRHANDLE
متغيرًا
سلميًا غير
معرف (أو
عنصر
مصفوفة أو
هاش)،
فسيُسند
إلى
المتغير
مرجع لمقبض
دليل مجهول
جديد؛ أي
أنه يُنشأ
آليًا (autovivified).
مقابض
الأدلة هي
نفس كائنات
مقابض
الملفات؛
يمكن لكائن
إدخال/إخراج
واحد أن
يكون
مفتوحًا
كواحد فقط
من أنواع
المقابض
هذه في كل
مرة.
راجع المثال في "readdir".
- ord EXPR
- ord
- يعيد نقطة
الترميز
للمحرف
الأول من EXPR.
إذا كان EXPR
سلسلة نصية
فارغة،
يعيد 0. إذا
حُذف EXPR،
يستخدم
$_. (لاحظ
محرف،
وليس بايت.)
للعكس، راجع "chr". راجع perlunicode لمزيد عن يونيكود.
- our VARLIST
- our TYPE VARLIST
- our VARLIST : ATTRS
- our TYPE VARLIST : ATTRS
- تقوم "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"، التي تسمح باستخدام اسم غير مؤهل فقط داخل الحزمة المتأثرة، ولكن عبر النطاقات.
- pack TEMPLATE,LIST
- تأخذ LIST من
القيم
وتحولها
إلى سلسلة
نصية
باستخدام
القواعد
المحددة
بواسطة TEMPLATE.
السلسلة
الناتجة هي
دمج للقيم
المحولة.
عادةً ما
تبدو كل
قيمة محولة
مثل
تمثيلها
على مستوى
الآلة. على
سبيل
المثال، في
الآلات ذات
32 بت، قد
يُمثل
العدد
الصحيح
بتسلسل من 4
بايتات،
والتي
ستُقدم في Perl
كسلسلة
نصية طولها
4 محارف.
راجع perlpacktut لمقدمة حول هذه الدالة.
TEMPLATE هو تسلسل من المحارف التي تحدد ترتيب ونوع القيم، كما يلي:
a سلسلة نصية ببيانات ثنائية عشوائية، ستُحشى بالأصفار (null). A سلسلة نصية نصية (ASCII)، ستُحشى بالمسافات. Z سلسلة نصية منتهية بـ null (ASCIZ)، ستُحشى بالأصفار. b سلسلة بتات (ترتيب بتات تصاعدي داخل كل بايت، مثل vec()). B سلسلة بتات (ترتيب بتات تنازلي داخل كل بايت). h سلسلة ست عشرية (النيبل المنخفض أولاً). H سلسلة ست عشرية (النيبل المرتفع أولاً). c قيمة محرف موقعة (8 بت). C قيمة محرف غير موقعة (ثمانية). W قيمة محرف غير موقعة (يمكن أن تكون أكبر من 255). s قيمة short موقعة (16 بت). S قيمة short غير موقعة. l قيمة long موقعة (32 بت). L قيمة long غير موقعة. q قيمة quad موقعة (64 بت). Q قيمة quad غير موقعة. (قيم Quad متوفرة فقط إذا كان نظامك يدعم قيم أعداد صحيحة بـ 64 بت _و_ إذا بُنيت Perl لتدعم ذلك. تثير استثناءً خلاف ذلك.) i قيمة عدد صحيح موقعة. I قيمة عدد صحيح غير موقعة. (هذا الـ 'عدد صحيح' بعرض 32 بت على الأقل. يعتمد حجمه الدقيق على ما يسميه مترجم C المحلي 'int'.) n قيمة short غير موقعة (16 بت) بترتيب "الشبكة" (big-endian). N قيمة long غير موقعة (32 بت) بترتيب "الشبكة" (big-endian). v قيمة short غير موقعة (16 بت) بترتيب "VAX" (little-endian). V قيمة long غير موقعة (32 بت) بترتيب "VAX" (little-endian). j قيمة عدد صحيح موقعة داخلية لـ Perl (IV). J قيمة عدد صحيح غير موقعة داخلية لـ Perl (UV). f قيمة فاصلة عائمة بدقة مفردة بالصيغة الأصلية. d قيمة فاصلة عائمة بدقة مزدوجة بالصيغة الأصلية. F قيمة فاصلة عائمة داخلية لـ Perl (NV) بالصيغة الأصلية D قيمة فاصلة عائمة بدقة long-double بالصيغة الأصلية. (قيم Long double متوفرة فقط إذا كان نظامك يدعمها. تثير استثناءً خلاف ذلك. لاحظ وجود تنسيقات مختلفة للـ long double.) p مؤشر لسلسلة نصية منتهية بـ null. P مؤشر لهيكل (سلسلة نصية ثابتة الطول). u سلسلة نصية بترميز uuencoded. U رقم محرف يونيكود. يرمز إلى محرف في نمط المحارف وإلى UTF-8 (أو UTF-EBCDIC في منصات EBCDIC) في نمط البايت. أيضًا في منصات EBCDIC، سيكون رقم المحرف هو قيمة EBCDIC الأصلية لأرقام المحارف الأقل من 256. يسمح هذا لمعظم البرامج بألا تهتم بنوع المنصة التي تعمل عليها. w عدد صحيح مضغوط BER (ليس ASN.1 BER، راجع perlpacktut للتفاصيل). تمثل بايتاته عددًا صحيحًا غير موقع في الأساس 128، الرقم الأكثر أهمية أولاً، مع أقل عدد ممكن من الأرقام. يُضبط البت الثامن (البت العالي) في كل بايت باستثناء الأخير. x بايت null (يُعرف أيضًا بـ ASCII NUL، "\000"، chr(0)) X الرجوع بايت واحد للخلف. @ الحشو بـ null أو الاقتطاع إلى موضع مطلق، يُحسب من بداية المجموعة () الداخلية. . الحشو بـ null أو الاقتطاع إلى موضع مطلق محدد بواسطة القيمة. ( بداية مجموعة ().قد يتبع واحد أو أكثر من المعدلات أدناه اختياريًا أحرفًا معينة في 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"
سلسلة بطول
تلك البتات.
يولّد كل
تنسيق من
هذا القبيل
بتّاً
واحداً من
النتيجة.
وعادة ما
تتبع هذه
التنسيقات
بعدد تكرار
مثل "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","hello,","world") "\000\006hello,\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) من رائعة جوناثان سويفت الساخرة، Gulliver's Travels. دخل هذا في لغة الحاسوب عبر ورقة بعنوان "حول الحروب المقدسة والتماس من أجل السلام" بقلم داني كوهين، 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ترتيب البايتات "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"
ومجموعات
"()"،
بمعدلات
النهاية
">" أو
"<" لفرض
ترتيب
البايتات
للنهاية
الكبرى أو
الصغرى على
التوالي.
هذه
المعدلات
مفيدة بشكل
خاص نظرًا
لأن "n" و
"N" و
"v" و
"V" لا
تغطي
الأعداد
الصحيحة
الموقعة،
أو الأعداد
الصحيحة 64
بت، أو قيم
الفاصلة
العائمة.
فيما يلي بعض الاعتبارات التي يجب وضعها في الاعتبار عند استخدام معدل النهاية:
- يعمل تبادل الأعداد الصحيحة الموقعة بين المنصات المختلفة فقط عندما تخزنها جميع المنصات في نفس التنسيق. تخزن معظم المنصات الأعداد الصحيحة الموقعة بنظام المتمم الثنائي (two's-complement)، لذا فعادة ما لا يمثل هذا مشكلة.
- لا يمكن استخدام معدلات ">" أو "<" على تنسيقات الفاصلة العائمة إلا في آلات النهاية الكبرى أو الصغرى. بخلاف ذلك، فإن محاولة استخدامها تثير استثناءً.
- يمكن أن ينجح فرض ترتيب البايتات للنهاية الكبرى أو الصغرى على قيم الفاصلة العائمة لتبادل البيانات فقط إذا كانت جميع المنصات تستخدم نفس التمثيل الثنائي مثل فاصلة IEEE العائمة. وحتى لو كانت جميع المنصات تستخدم IEEE، فقد تظل هناك اختلافات طفيفة. إن القدرة على استخدام ">" أو "<" على قيم الفاصلة العائمة يمكن أن تكون مفيدة، ولكنها خطيرة أيضًا إذا لم تكن تعرف بالضبط ما تفعله. إنها ليست طريقة عامة لتخزين قيم الفاصلة العائمة بشكل محمول.
- عند استخدام ">" أو "<" على مجموعة "()"، فإن هذا يؤثر على جميع الأنواع داخل المجموعة التي تقبل معدلات ترتيب البايتات، بما في ذلك جميع المجموعات الفرعية. ويُتجاهل بصمت لجميع الأنواع الأخرى. لا يُسمح لك بتجاوز ترتيب البايتات داخل مجموعة تحتوي بالفعل على لاحقة معدل ترتيب البايتات.
- الأرقام
الحقيقية (floats
و doubles) تكون
بتنسيق
الآلة
الأصلي فقط.
نظرًا
لتعدد
تنسيقات
الفاصلة
العائمة
وعدم وجود
تمثيل
قياسي
"للشبكة"
لها، لم
يُنشأ أي
مرفق
للتبادل.
وهذا يعني
أن بيانات
الفاصلة
العائمة
المحزومة
المكتوبة
على آلة
واحدة قد لا
تكون قابلة
للقراءة
على آلة
أخرى، حتى
لو كانت
كلتاهما
تستخدمان
حسابات
الفاصلة
العائمة IEEE
(لأن نهاية
تمثيل
الذاكرة
ليس جزءًا
من مواصفات
IEEE). انظر
أيضًا perlport.
إذا كنت تعرف exactly ما تفعله، يمكنك استخدام معدلات ">" أو "<" لفرض ترتيب البايتات للنهاية الكبرى أو الصغرى على قيم الفاصلة العائمة.
لأن 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
مرة أخرى.
لذلك، فإن
نتيجة
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 بت بترتيب النهاية الكبرى/الصغرى (big-/little-endian). هذا الأمر قابل للنقل فقط عندما تستخدم جميع المنصات التي تتشارك البيانات المحزومة نفس التمثيل الثنائي للأعداد الصحيحة الموقعة؛ على سبيل المثال، عندما تستخدم جميع المنصات تمثيل المتمم الثنائي.
- يمكن تضمين التعليقات في القالب (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.
- package NAMESPACE
- package NAMESPACE VERSION
- package NAMESPACE BLOCK
- package NAMESPACE VERSION BLOCK
- يعلن عن
الكتلة (BLOCK) أو
بقية وحدة
التصريف
كأنها
تنتمي
لمجال
الأسماء
المعطى.
يكون نطاق
تصريح
الحزمة إما
كتلة الكود
المزودة،
أو في حال
غياب
الكتلة،
فمن
التصريح
نفسه حتى
نهاية
النطاق
الحالي
(الكتلة
المحيطة،
أو الملف،
أو eval). أي
أن الأشكال
التي لا
تحتوي على
كتلة تكون
فاعلة حتى
نهاية
النطاق
الحالي،
تمامًا مثل
العوامل
my و state و
our. جميع
المعرفات
الديناميكية
غير
المؤهلة في
هذا النطاق
ستكون في
مجال
الأسماء
المعطى، ما
لم يتم
تجاوزها
بتصريح
package آخر أو
عندما تكون
أحد
المعرفات
الخاصة
التي تتأهل
إلى main::،
مثل STDOUT و
ARGV و ENV و
متغيرات
الترقيم.
يؤثر بيان الحزمة (package) على المتغيرات الديناميكية فقط، بما في ذلك تلك التي استخدمت عليها local، ولكن ليس المتغيرات ذات النطاق المجمعي (lexically-scoped)، التي أُنشئت باستخدام my أو state أو our. عادةً ما يكون أول تصريح في ملف مضمن بواسطة require أو use. يمكنك الانتقال إلى حزمة في أكثر من مكان، لأن هذا يحدد فقط جدول الرموز المبدئي الذي يستخدمه المصرف لبقية تلك الكتلة. يمكنك الإشارة إلى المعرفات في حزم أخرى غير الحالية عن طريق بادئة المعرف باسم الحزمة ونقطتين مزدوجتين، كما في $SomePack::var أو ThatPack::INPUT_HANDLE. إذا حُذف اسم الحزمة، تُفترض الحزمة main. أي أن $::sail تكافئ $main::sail (وكذلك $main'sail، التي لا تزال تُرى في الأكواد القديمة جدًا، غالبًا من Perl 4).
إذا تم توفير VERSION، يضبط package المتغير $VERSION في مجال الأسماء المعطى إلى كائن إصدار بالإصدار الموفر. يجب أن يكون VERSION رقم إصدار بنمط "صارم" كما هو محدد بواسطة وحدة الإصدار: رقم عشري موجب (صحيح أو كسر عشري) بدون أس أو سلسلة v ذات نقاط (v-string) تبدأ بحرف '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 - pipe READHANDLE,WRITEHANDLE
- يفتح زوجًا
من
الأنابيب
المتصلة
مثل
استدعاء
النظام
المقابل.
لاحظ أنه
إذا قمت
بإعداد
حلقة من
العمليات
الأنبوبية،
فقد يحدث
استعصاء (deadlock)
ما لم تكن
حذرًا جدًا.
بالإضافة
إلى ذلك،
لاحظ أن
أنابيب Perl
تستخدم
التخزين
المؤقت
للإدخال
والإخراج،
لذا قد
تحتاج لضبط
$|
لتفريغ WRITEHANDLE
بعد كل أمر،
اعتمادًا
على
التطبيق.
يعيد قيمة صواب عند النجاح.
انظر IPC::Open2 و IPC::Open3 و "Bidirectional Communication with Another Process" في perlipc لأمثلة على مثل هذه الأشياء.
في الأنظمة التي تدعم علامة الإغلاق عند التنفيذ (close-on-exec) على الملفات، تُضبط هذه العلامة على جميع واصفات الملفات المفتوحة حديثًا التي تكون قيم fileno الخاصة بها أعلى من القيمة الحالية لـ $^F (افتراضيًا 2 لـ STDERR). انظر "$^F" في perlvar.
- pop ARRAY
- pop
- يزيل ويعيد
العنصر
الأخير من
المصفوفة،
ويقصر
المصفوفة
بمقدار
عنصر واحد.
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
- pos
- يعيد إزاحة
المكان
الذي توقف
عنده آخر
بحث 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.
تُطبع القيمة الحالية لـ $, (إن وجدت) بين كل عنصر في القائمة. وتُطبع القيمة الحالية لـ $\ (إن وجدت) بعد طباعة القائمة بالكامل. ولأن 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
- printf
- تكافئ 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
- prototype
- تعيد
النموذج
الأولي
للدالة
كسلسلة (أو
undef إذا لم
يكن للدالة
نموذج
أولي). FUNCTION هي
مرجع
للدالة، أو
اسمها،
التي تريد
استعادة
نموذجها
الأولي. إذا
حُذفت FUNCTION،
تُستخدم
$_.
إذا كانت FUNCTION سلسلة تبدأ بـ CORE::، يُؤخذ الباقي كاسم لدالة Perl مدمجة. إذا لم تكن وسائط الدالة المدمجة قابلة للتعبير عنها بشكل كافٍ بواسطة نموذج أولي (مثل system)، تعيد prototype القيمة undef، لأن الدالة المدمجة لا تتصرف حقًا مثل دالة Perl. خلاف ذلك، تُعاد السلسلة التي تصف النموذج الأولي المكافئ.
- push ARRAY,LIST
- تضيف
عنصرًا
واحدًا أو
أكثر إلى
نهاية
المصفوفة.
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.
- q/STRING/
- qq/STRING/
- qw/STRING/
- qx/STRING/
- عوامل اقتباس معممة. انظر "Quote-Like Operators" في perlop.
- qr/STRING/
- اقتباس شبيه بالتعابير النمطية. انظر "Regexp Quote-Like Operators" في perlop.
- quotemeta EXPR
- quotemeta
- يعيد قيمة EXPR
مع إضافة
شرطة مائلة
خلفية
لجميع
محارف ASCII غير
"الكلمية".
(بمعنى أن
كل محارف ASCII
التي لا
تطابق
"/[A-Za-z_0-9]/"
ستُسبق
بشرطة
مائلة
خلفية في
السلسلة
المعادة،
بغض النظر
عن أي
إعدادات
محلية.) هذه
هي الدالة
الداخلية
التي تنفذ
هروب "\Q"
في السلاسل
المقتبسة
اقتباساً
مزدوجاً.
(انظر أدناه
لمعرفة
السلوك مع
نقاط ترميز
غير ASCII.)
إذا حُذفت EXPR، تُستخدم $_.
تعد 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
- rand
- تعيد رقمًا
كسريًا
عشوائيًا
أكبر من أو
يساوي 0
وأقل من
قيمة EXPR. (يجب
أن تكون EXPR
موجبة). إذا
حُذفت EXPR،
تُستخدم
القيمة
1.
حاليًا،
يتم
التعامل مع
EXPR بالقيمة
0 كحالة
خاصة لتكون
1 (لم يكن
هذا موثقًا
قبل Perl 5.8.0 وهو
عرضة
للتغيير في
إصدارات Perl
المستقبلية).
تستدعي
srand آليًا
ما لم يكن
قد استُدعي
srand
بالفعل.
انظر أيضًا
srand.
طبق int على القيمة المعادة من rand إذا كنت تريد أعدادًا صحيحة عشوائية بدلاً من أعداد كسرية عشوائية. على سبيل المثال،
int(rand(10))تُعيد عدداً صحيحاً عشوائياً بين 0 و 9، على نحوٍ شامل.
(ملاحظة: إذا كانت دالة rand الخاصة بك تُعيد أرقاماً كبيرة جداً أو صغيرة جداً باستمرار، فمن المحتمل أن نسخة Perl لديك قد جُمّعت مع عدد خاطئ من RANDBITS.)
"rand" ليست آمنة تعموياً. يجب ألا تعتمد عليها في المواقف الحساسة أمنياً. حتى وقت كتابة هذا الدليل، توفر عدة وحدات CPAN من جهات خارجية مولدات أرقام عشوائية يقصد مؤلفوها أن تكون آمنة تعموياً، بما في ذلك: Data::Entropy، و Crypt::Random، و Math::Random::Secure، و Math::TrulyRandom.
- read FILEHANDLE,SCALAR,LENGTH,OFFSET
- read FILEHANDLE,SCALAR,LENGTH
- تحاول
قراءة
محارف
بطول LENGTH من
البيانات
إلى
المتغير SCALAR
من ممسك
الملف FILEHANDLE
المحدد.
تُعيد عدد
المحارف
التي قُرئت
فعلياً، أو
0 عند
نهاية
الملف، أو undef
إذا حدث خطأ
(وفي الحالة
الأخيرة
يُضبط $!
أيضاً).
سيتم زيادة
حجم SCALAR أو
تقليصه
بحيث يكون
آخر محرف
قُرئ
فعلياً هو
آخر محرف في
المتغير
السلمي بعد
القراءة.
يمكن تحديد OFFSET لوضع البيانات المقروءة في مكان ما في السلسلة غير البداية. تحدد الإزاحة OFFSET السالبة الموضع بعدد من المحارف بالعد تنازلياً من نهاية السلسلة. أما الإزاحة OFFSET الموجبة الأكبر من طول SCALAR فتؤدي إلى حشو السلسلة إلى الحجم المطلوب ببايتات "\0" قبل إلحاق نتيجة القراءة.
نُفّذ هذا الاستدعاء بناءً على دالة مكتبة fread(3) الأصيلة سواء الخاصة بـ Perl أو بنظامك، عبر طبقات PerlIO المطبقة على الممسك. للحصول على استدعاء نظام read(2) حقيقي، انظر sysread.
لاحظ الـ محارف: اعتمادًا على حالة مقبض الملف، تُقرأ إما بايتات (8-بت) أو محارف. مبدئيًا، تعمل جميع مقابض الملفات على البايتات، ولكن على سبيل المثال إذا فُتح مقبض الملف باستخدام طبقة الإدخال/الإخراج ":utf8" (انظر "open"، والموجه open)، فستعمل عملية الإدخال/الإخراج على محارف يونيكود مرمزة بـ UTF8، وليس بايتات. وينطبق الشيء نفسه على طبقة ":encoding": في هذه الحالة يمكن قراءة أي محارف تقريبًا.
- readdir DIRHANDLE
- تُعيد مدخل
الدليل
التالي
لدليل وُصل
بواسطة
"opendir". إذا
استُخدمت
في سياق
قائمة،
تُعيد جميع
الإدخالات
المتبقية
في الدليل.
إذا لم يعد
هناك
المزيد من
الإدخالات،
تُعيد
القيمة غير
المعرفة في
سياق
المتغير
السلمي
والقائمة
الفارغة في
سياق
القائمة.
إذا كنت تخطط لإجراء اختبار ملف (filetest) على القيم المعادة من "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
- readline
- تقرأ من
ممسك الملف
الذي يوجد 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"، فإن الشرط يختبر فعلياً تعريف قيمة التعبير، وليس قيمته المنطقية العادية.
- readlink EXPR
- readlink
- تُعيد قيمة
الوصلة
الرمزية،
إذا كانت
الوصلات
الرمزية
مدعومة. إذا
لم تكن
كذلك، تثير
استثناءً.
إذا كان
هناك خطأ في
النظام،
تُعيد
القيمة غير
المعرفة
وتضبط $!
(رقم الخطأ).
إذا حُذفت
EXPR، تستخدم
$_.
مشاكل النقلية: "readlink" في perlport.
- readpipe EXPR
- readpipe
- تُنفذ EXPR كأمر نظام. يُعاد الناتج القياسي المجمع للأمر. في سياق المتغير السلمي، تُعاد كسلسلة واحدة (قد تكون متعددة الأسطر). في سياق القائمة، تُعيد قائمة من الأسطر (حسبما قمت بتعريف الأسطر باستخدام $/ (أو $INPUT_RECORD_SEPARATOR بالإنجليزية)). هذه هي الدالة الداخلية التي تُنفذ عامل "qx/EXPR/"، ولكن يمكنك استخدامها مباشرة. يُناقش عامل "qx/EXPR/" بمزيد من التفصيل في ""qx/STRING/"" في perlop. إذا حُذفت EXPR، تستخدم $_.
- recv SOCKET,SCALAR,LENGTH,FLAGS
- تستقبل
رسالة على
مقبس. تحاول
استقبال LENGTH
محارف من
البيانات
إلى
المتغير SCALAR
من ممسك
الملف SOCKET
المحدد.
سيتم زيادة
حجم SCALAR أو
تقليصه إلى
الطول
المقروء
فعلياً.
تأخذ نفس
الأعلام
التي
يأخذها
استدعاء
النظام
الذي يحمل
نفس الاسم.
تُعيد
عنوان
المرسل إذا
كان
بروتوكول SOCKET
يدعم ذلك؛
وتُعيد
سلسلة
فارغة خلاف
ذلك. إذا
حدث خطأ،
تُعيد
القيمة غير
المعرفة.
هذا
الاستدعاء
نُفذ
فعلياً
بناءً على
استدعاء
النظام recvfrom(2).
انظر "UDP:
تمرير
الرسائل"
في perlipc للحصول
على أمثلة.
لاحظ أنه إذا تم وسم المقبس بـ ":utf8"، فإن "recv" ستثير استثناءً. تُقدم طبقة :encoding(...) ضمنياً طبقة ":utf8". انظر "binmode".
- redo LABEL
- redo EXPR
- redo
- يعيد أمر
"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
- ref
- تفحص قيمة
EXPR، متوقعةً
أن تكون
مرجعاً،
وتُعيد
سلسلة نصية
تعطي
معلومات
حول المرجع
ونوع
المشار
إليه. إذا
لم يتم
تحديد EXPR،
سيتم
استخدام
$_.
إذا لم يكن المعامل مرجعاً، فسيتم إرجاع سلسلة فارغة. لن يتم إرجاع سلسلة فارغة إلا في هذه الحالة. غالباً ما تكون "ref" مفيدة لمجرد اختبار ما إذا كانت القيمة مرجعاً، وهو ما يمكن فعله بمقارنة النتيجة بالسلسلة الفارغة. من الأخطاء الشائعة استخدام نتيجة "ref" مباشرة كقيمة منطقية: هذا يخطئ لأن القيمة 0 (وهي خطأ) يمكن أن تُعاد من أجل المرجع.
إذا كان المعامل مرجعاً لكائن مبارك (blessed object)، فسيتم إرجاع اسم الصنف الذي بورك فيه المشار إليه. لا تهتم "ref" بالنوع المادي للمشار إليه؛ فالمباركة تأخذ الأسبقية على مثل هذه الاهتمامات. احذر من أن المقارنة الدقيقة لنتائج "ref" مع اسم الصنف لا تجري اختبار عضوية الصنف: إذ تشمل أعضاء الصنف أيضاً الكائنات المباركة في أصناف فرعية، والتي ستعيد "ref" اسم الصنف الفرعي لها. احذر أيضاً من أن أسماء الأصناف قد تتصادم مع أسماء الأنواع المضمنة (الموضحة أدناه).
إذا كان المعامل مرجعاً لكائن غير مبارك، فإن القيمة المعادة تشير إلى نوع الكائن. إذا لم يكن المشار إليه غير المبارك متغيراً سلمياً، فستكون القيمة المعادة إحدى السلاسل "ARRAY" أو "HASH" أو "CODE" أو "FORMAT" أو "IO"، مما يشير فقط إلى نوع الكائن. إذا كان المشار إليه غير المبارك متغيراً سلمياً، فستكون القيمة المعادة إحدى السلاسل "SCALAR" أو "VSTRING" أو "REF" أو "GLOB" أو "LVALUE" أو "REGEXP"، اعتماداً على نوع القيمة التي يحملها المتغير السلمي حالياً. ولكن لاحظ أن المتغيرات السلمية "qr//" تُنشأ مباركة بالفعل، لذا فمن المرجح أن "ref qr/.../" ستعيد "Regexp". احذر من أن أسماء الأنواع المضمنة هذه يمكن استخدامها أيضاً كأسماء أصناف، لذا فإن إرجاع "ref" لأحد هذه الأسماء لا يشير بشكل لا لبس فيه إلى أن المشار إليه هو من النوع الذي يشير إليه الاسم.
يحد الغموض بين أسماء الأنواع المضمنة وأسماء الأصناف بشكل كبير من فائدة "ref". للحصول على معلومات غير غامضة، استخدم Scalar::Util::blessed() للحصول على معلومات حول المباركة، و Scalar::Util::reftype() للحصول على معلومات حول الأنواع المادية. استخدم توابع "isa" لاختبارات عضوية الصنف، رغم أنه يجب التأكد من المباركة قبل محاولة استدعاء التابع. كبديل، يمكن لعامل "isa" اختبار عضوية الصنف دون التحقق من المباركة أولاً.
انظر أيضاً perlref و perlobj.
- rename OLDNAME,NEWNAME
- تغير اسم
ملف؛ وسيتم
طمس أي ملف NEWNAME
موجود.
تُعيد true
للنجاح؛
وعند
الإخفاق
تُعيد false
وتضبط $!.
يختلف سلوك هذه الدالة بشكل كبير اعتماداً على تنفيذ نظامك. على سبيل المثال، لن تعمل عادةً عبر حدود أنظمة الملفات، رغم أن أمر نظام التشغيل mv يعوض عن ذلك أحياناً. تشمل القيود الأخرى ما إذا كانت تعمل على الأدلة، أو الملفات المفتوحة، أو الملفات الموجودة مسبقاً. تحقق من perlport وإما صفحة دليل rename(2) أو توثيق النظام المكافئ لمزيد من التفاصيل.
للحصول على دالة "move" مستقلة عن المنصة، انظر إلى وحدة File::Copy.
مشاكل النقلية: "rename" في perlport.
- require VERSION
- require EXPR
- require
- تتطلب
إصداراً من
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 ..."; }لاحظ أن الملف لن يتم تضمينه مرتين تحت نفس الاسم المحدد.
تاريخياً، يجب أن يعيد الملف true كآخر جملة للإشارة إلى نجاح تنفيذ أي شفرة تهيئة، لذا جرت العادة على إنهاء مثل هذا الملف بـ "1;" إلا إذا كنت متأكداً من أنه سيعيد true بخلاف ذلك. ولكن من الأفضل وضع "1;" تحسباً لإضافة المزيد من الجمل. بدءاً من 5.37.6، يمكن تجنب هذا المتطلب بتمكين ميزة 'module_true'، والتي تُمكّن آلياً في حزم الإصدارات الحديثة. وبالتالي فإن الشفرة التي تستخدم "use v5.37;" لم تعد بحاجة للانشغال بهذه المسألة. انظر feature لمزيد من التفاصيل. لاحظ أن هذا يؤثر على وحدة التجميع التي تُستخدم الميزة ضمنها، واستخدامها قبل طلب وحدة (module) لن يغير سلوك الوحدات الحالية التي لا تستخدم هي نفسها هذه الميزة.
إذا كان 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(...);
إذا كان الخطاف مرجع مصفوفة، فيجب أن يكون عنصره الأول مرجع برنامج فرعي أو كائناً كما هو موضح أعلاه. عندما يكون العنصر الأول كائناً يدعم تابع "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
- reset
- يُستخدم
عموماً في
كتلة
"continue" في
نهاية حلقة
لمسح
المتغيرات
وإعادة ضبط
عمليات بحث
"m?pattern?"
لتعمل مرة
أخرى. يُفسر
التعبير
كقائمة من
أحرف مفردة
(يُسمح
بالواصلات
للنطاقات).
جميع
المتغيرات
(القيم
القياسية،
المصفوفات،
والمجموعات)
في الحزمة
الحالية
التي تبدأ
بأحد تلك
الأحرف
تُعاد إلى
حالتها
الأصلية.
إذا حُذف
التعبير،
تُعاد
عمليات
البحث ذات
المطابقة
الواحدة
("m?pattern?")
لتطابق مرة
أخرى. يعيد
الضبط فقط
للمتغيرات
أو عمليات
البحث في
الحزمة
الحالية.
يعيد
دائماً 1.
أمثلة:
reset 'X'; # إعادة ضبط جميع متغيرات X reset 'a-z'; # إعادة ضبط المتغيرات الصغيرة reset; # فقط إعادة ضبط عمليات بحث m?one-time?لا يوصى بإعادة ضبط "A-Z" لأنك ستمسح مصفوفات @ARGV و @INC ومجموعة %ENV.
يعيد ضبط متغيرات الحزمة فقط؛ المتغيرات المعجمية (lexical) لا تتأثر، لكنها تنظف نفسها عند الخروج من النطاق على أي حال، لذا فمن المحتمل أنك سترغب في استخدامها بدلاً من ذلك. راجع "my".
- return EXPR
- return
- يعود من
دالة
فرعية، أو
"eval"، أو
"do FILE"، أو
كتلة "sort"
أو كتلة eval
لتعبير
نمطي (ولكن
ليس كتلة
"grep" أو
"map" أو
"do BLOCK")
بالقيمة
المعطاة في
EXPR. قد يكون
تقييم EXPR في
سياق قائمة
أو سياق
قياسي أو
سياق باطل،
اعتماداً
على كيفية
استخدام
القيمة
المعادة،
وقد يختلف
السياق من
تنفيذ لآخر
(راجع
"wantarray"). إذا
لم يُعطَ EXPR،
فإنه يعيد
قائمة
فارغة في
سياق
القائمة،
والقيمة
غير
المعرفة (undefined)
في السياق
القياسي،
و(بالطبع)
لا شيء على
الإطلاق في
السياق
الباطل.
(في غياب "return" صريح، تعيد الدالة الفرعية أو "eval" أو "do FILE" آلياً قيمة آخر تعبير جرى تقييمه.)
على عكس معظم المعاملات المسماة، يُعفى هذا أيضاً من قاعدة "يبدو كدالة"، لذا فإن "return ("foo")."bar"" سيجعل "bar" جزءاً من المعامل الممرر لـ "return".
- reverse LIST
- في سياق
القائمة،
يعيد قيمة
قائمة
تتكون من
عناصر 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; # عكس المجموعة - rewinddir DIRHANDLE
- يضبط
الموضع
الحالي إلى
بداية
الدليل
لروتين
"readdir" على
DIRHANDLE.
مسائل القابلية للنقل: "rewinddir" في perlport.
- rindex STR,SUBSTR,POSITION
- rindex STR,SUBSTR
- يعمل تماماً مثل "index" باستثناء أنه يعيد موضع آخر ظهور لـ SUBSTR في STR. إذا جرى تحديد POSITION، فإنه يعيد آخر ظهور يبدأ عند ذلك الموضع أو قبله.
- rmdir FILENAME
- rmdir
- يحذف
الدليل
المحدد
بواسطة FILENAME
إذا كان هذا
الدليل
فارغاً. إذا
نجح، يعيد
true؛ وإلا
يعيد false
ويضبط
$! (errno). إذا
حُذف FILENAME،
يستخدم
$_.
لإزالة شجرة دليل بشكل متكرر ("rm -rf" على يونكس) راجع دالة "rmtree" في وحدة File::Path.
- s///
- معامل الاستبدال. راجع "Regexp Quote-Like Operators" في perlop.
- say FILEHANDLE LIST
- say FILEHANDLE
- say LIST
- say
- تماماً مثل
"print"،
ولكنه يلحق
سطراً
جديداً
ضمنياً في
نهاية LIST
بدلاً من أي
قيمة قد
تحملها
"$\".
لاستخدام
FILEHANDLE بدون LIST
لطباعة
محتويات
$_ إليه،
يجب
استخدام
مقبض ملف
صريح مثل
"FH"،
وليس
مقبضاً غير
مباشر مثل
$fh.
دالة "say" متاحة فقط إذا تم تمكين ميزة "say" أو إذا كانت مسبوقة بـ "CORE::". يتم تمكين ميزة "say" تلقائيًا عند التصريح عن استخدام "use v5.10" (أو إصدار أحدث) في النطاق الحالي.
- scalar EXPR
- يجبر 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 للحصول على تفاصيل حول تقييم المجموعة في سياق قياسي.
- seek FILEHANDLE,POSITION,WHENCE
- يضبط موضع
FILEHANDLE، تماماً
مثل
استدعاء fseek(3)
في C "stdio".
قد يكون FILEHANDLE
تعبيراً
تعطي قيمته
اسم مقبض
الملف. قيم WHENCE
هي 0
لضبط
الموضع
الجديد
بالبايت
إلى POSITION؛ و
1 لضبطه
إلى الموضع
الحالي
زائد POSITION؛ و
2 لضبطه
إلى نهاية
الملف (EOF)
زائد POSITION،
وعادة ما
تكون سالبة.
بالنسبة لـ
WHENCE، يمكنك
استخدام
الثوابت
"SEEK_SET" و
"SEEK_CUR" و
"SEEK_END"
(بداية
الملف،
الموضع
الحالي،
نهاية
الملف) من
وحدة Fcntl. يعيد
1 عند
النجاح، و false
بخلاف ذلك.
لاحظ التأكيد على البايتات: حتى لو ضُبط مقبض الملف ليعمل على الأحرف (على سبيل المثال باستخدام طبقة الإدخال/الإخراج :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" التالية لغة بيرل تحاول مرة أخرى قراءة شيء ما. (نأمل ذلك.)
إذا لم ينجح ذلك (بعض تطبيقات الإدخال/الإخراج سيئة المزاج بشكل خاص)، فقد تحتاج إلى شيء كهذا:
for (;;) { for ($curpos = tell($fh); $_ = readline($fh); $curpos = tell($fh)) { # البحث عن بعض الأشياء ووضعها في ملفات } sleep($for_a_while); seek($fh, $curpos, 0); } - seekdir DIRHANDLE,POS
- يضبط الموضع الحالي لروتين "readdir" على DIRHANDLE. يجب أن تكون POS قيمة معادة بواسطة "telldir". تمتلك "seekdir" أيضاً نفس المحاذير المتعلقة باحتمالية ضغط الدليل كما في روتين مكتبة النظام المقابل.
- select FILEHANDLE
- select
- يعيد مقبض
الملف
المختار
حالياً. إذا
جرى توفير
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.
- semctl ID,SEMNUM,CMD,ARG
- يستدعي
وظيفة 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.
- semget KEY,NSEMS,FLAGS
- يستدعي
وظيفة System V IPC
semget(2). يعيد
معرف
السيمافور،
أو القيمة
غير
المعرفة
عند الخطأ.
راجع أيضاً
"SysV IPC" في perlipc
والتوثيق
لـ "IPC::SysV" و
"IPC::Semaphore".
مسائل القابلية للنقل: "semget" في perlport.
- semop KEY,OPSTRING
- يستدعي
وظيفة 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.
- send SOCKET,MSG,FLAGS,TO
- send SOCKET,MSG,FLAGS
- يرسل رسالة
عبر سوكيت.
يحاول
إرسال
القيمة
القياسية MSG
إلى مقبض
الملف SOCKET.
يأخذ نفس
الأعلام (flags)
كاستدعاء
النظام
الذي يحمل
نفس الاسم.
في
السوكيتات
غير
المتصلة،
يجب تحديد
وجهة لـ
الإرسال
إليها،
وفي هذه
الحالة
يقوم
باستدعاء
نظام sendto(2).
يعيد عدد
الأحرف
المرسلة،
أو القيمة
غير
المعرفة
عند الخطأ.
استدعاء
النظام sendmsg(2)
غير مطبق
حالياً.
راجع "UDP: Message Passing"
في perlipc
للأمثلة.
لاحظ أنه إذا وُسم السوكيت بـ ":utf8"، فإن "send" سيرمي استثناءً. طبقة :encoding(...) تقدم طبقة ":utf8" ضمنياً. راجع "binmode".
- setpgrp PID,PGRP
- يضبط
مجموعة
العمليات
الحالية لـ
PID المحدد، و
0
للعملية
الحالية.
يرفع
استثناءً
عند
استخدامه
على جهاز لا
يطبق POSIX setpgid(2) أو
BSD setpgrp(2). إذا
حُذفت
المعاملات،
فإن القيمة
المبدئية
هي "0,0".
لاحظ أن
نسخة BSD 4.2 من
"setpgrp" لا
تقبل أي
معاملات،
لذا فإن
"setpgrp(0,0)" فقط
هي القابلة
للنقل. راجع
أيضاً
POSIX::setsid().
مسائل القابلية للنقل: "setpgrp" في perlport.
- setpriority WHICH,WHO,PRIORITY
- يضبط
الأولوية
الحالية
لعملية، أو
مجموعة
عمليات، أو
مستخدم.
(راجع setpriority(2).)
يرفع
استثناءً
عند
استخدامه
على جهاز لا
يطبق setpriority(2).
يمكن أن تكون "WHICH" أي واحدة من "PRIO_PROCESS"، أو "PRIO_PGRP"، أو "PRIO_USER" المستوردة من "RESOURCE CONSTANTS" في POSIX.
مسائل القابلية للنقل: "setpriority" في perlport.
- setsockopt SOCKET,LEVEL,OPTNAME,OPTVAL
- يضبط خيار
السوكيت
المطلوب.
يعيد "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
- shift
- يزيل ويعيد
العنصر
الأول من
المصفوفة.
هذا يقصر
المصفوفة
بمقدار
عنصر واحد
وينقل كل
شيء لأسفل.
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" على الطرف الأيمن.
- shmctl ID,CMD,ARG
- يستدعي
دالة 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.
- shmget KEY,SIZE,FLAGS
- يستدعي
دالة System V IPC
المسماة shmget.
يعيد معرف (id)
قطعة
الذاكرة
المشتركة،
أو "undef"
عند حدوث
خطأ. انظر
أيضًا "SysV IPC"
في perlipc
والتوثيق
الخاص بـ
"IPC::SysV".
مسائل قابلية النقل: "shmget" في perlport.
- shmread ID,VAR,POS,SIZE
- shmwrite ID,STRING,POS,SIZE
- يقرأ أو
يكتب في
قطعة
الذاكرة
المشتركة 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.
- shutdown SOCKET,HOW
- يُغلق
اتصال
المقبس
بالطريقة
المحددة في
HOW، والتي
لها
التفسير
ذاته
الموجود في
نداء
النظام (syscall)
الذي يحمل
الاسم نفسه.
shutdown($socket, 0); # توقفتُ/توقفنا عن قراءة البيانات shutdown($socket, 1); # توقفتُ/توقفنا عن كتابة البيانات shutdown($socket, 2); # توقفتُ/توقفنا عن استخدام هذا المقبسهذا مفيد مع المقابس عندما تريد إخبار الطرف الآخر بأنك انتهيت من الكتابة ولكن ليس القراءة، أو العكس. كما أنه شكل أكثر إصرارًا من close لأنه يعطل واصف الملف في أي نسخ متفرعة (forked) في العمليات الأخرى.
يعيد 1 في حال النجاح؛ وعند الخطأ، يعيد "undef" إذا لم يكن المعامل الأول مقبض ملف صالحًا، أو يعيد 0 ويضبط $! لأي فشل آخر.
- sin EXPR
- sin
- يعيد جيب (sine)
القيمة EXPR
(معبرًا
عنها
بالراديان).
إذا حُذفت
EXPR، يعيد جيب
$_.
لعملية جيب التمام العكسية، يمكنك استخدام دالة "Math::Trig::asin"، أو استخدام هذه العلاقة:
sub asin { atan2($_[0], sqrt(1 - $_[0] * $_[0])) } - sleep EXPR
- sleep
- يجعل
السكربت
ينام لعدد
(صحيح) 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 SOCKET,DOMAIN,TYPE,PROTOCOL
- يفتح
مقبسًا من
النوع
المحدد
ويوصله
بمقبض
الملف SOCKET.
تُحدد قيم DOMAIN
و TYPE و PROTOCOL بنفس
الطريقة
المتبعة في
نداء
النظام
الذي يحمل
الاسم نفسه.
يجب عليك
كتابة "use
Socket" أولاً
لاستيراد
التعريفات
المناسبة.
انظر
الأمثلة في
"Sockets: Client/Server Communication" في perlipc.
في الأنظمة التي تدعم علم الإغلاق عند التنفيذ (close-on-exec) في الملفات، سيُضبط العلم لواصف الملف المفتوح حديثًا، كما هو محدد بواسطة قيمة $^F. راجع "$^F" في perlvar.
- socketpair SOCKET1,SOCKET2,DOMAIN,TYPE,PROTOCOL
- يُنشئ
زوجًا غير
مسمى من
المقابس في
النطاق
المحدد،
ومن النوع
المحدد.
تُحدد 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.
- sort SUBNAME LIST
- sort BLOCK LIST
- sort LIST
- في سياق
القائمة،
تقوم هذه
الدالة
بفرز LIST
وتعيد قيمة
القائمة
المفرزة.
أما في
السياق
السلمي (scalar)،
فإن سلوك
"sort" غير
محدد.
إذا حُذفت SUBNAME أو BLOCK، يتم الـ "sort" بترتيب مقارنة السلاسل القياسي. إذا حُددت SUBNAME، فإنها تعطي اسم روتين فرعي يعيد قيمة رقمية أقل من، أو تساوي، أو أكبر من 0، اعتمادًا على كيفية ترتيب عناصر القائمة. (العاملان "<=>" و "cmp" مفيدان للغاية في هذه الروتينات.) قد يكون SUBNAME اسم متغير سلمي (بدون فهرس)، وفي هذه الحالة توفر القيمة اسم (أو مرجعًا لـ) الروتين الفرعي الفعلي المستخدم. وبدلاً من SUBNAME، يمكنك توفير BLOCK كروتين فرعي للفرز مجهول ومضمن.
إذا كان النموذج المبدئي للروتين الفرعي هو "($$)"، تُمرر العناصر المراد مقارنتها بالمرجع في @_، كما في الروتين الفرعي العادي. هذا أبطأ من الروتينات الفرعية التي ليس لها نموذج مبدئي، حيث تُمرر العناصر المراد مقارنتها إلى الروتين الفرعي كمتغيرات عالمية للحزمة $a و $b (انظر المثال أدناه).
إذا كان الروتين الفرعي XSUB، تُدفع العناصر المراد مقارنتها إلى المكدس (stack)، بالطريقة التي تُمرر بها المعاملات عادةً إلى XSUBs. لا يتم ضبط $a و $b.
تُمرر القيم المراد مقارنتها دائمًا بالمرجع ولا ينبغي تعديلها.
لا يمكنك أيضًا الخروج من كتلة الفرز أو الروتين الفرعي باستخدام أي من عوامل التحكم في الحلقات الموصوفة في perlsyn أو باستخدام "goto".
عندما يكون "use locale" (ولكن ليس "use locale ':not_characters'") مفعلًا، تقوم "sort LIST" بفرز LIST وفقًا لإعدادات المقارنة المحلية الحالية (collation locale). انظر perllocale.
تعيد "sort" أسماء مستعارة (aliases) تشير إلى القائمة الأصلية، تمامًا كما يفعل متغير الفهرس في حلقة for مع عناصر القائمة. وهذا يعني أن تعديل عنصر في القائمة المعادة من "sort" (على سبيل المثال، في "foreach" أو "map" أو "grep") يعدل في الواقع العنصر في القائمة الأصلية. وهذا أمر ينبغي تجنبه عادةً عند كتابة شيفرة برمجية واضحة.
تاريخيًا، تباينت Perl في مسألة ما إذا كان الفرز مستقرًا (stable) افتراضيًا. إذا كان الاستقرار مهمًا، فيمكن التحكم فيه صراحةً باستخدام براغما sort.
أمثلة:
# ترتيب معجمي 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 حسب القيمة بدلاً من المفتاح # باستخدام دالة مضمنة 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; # استخدام نموذج أولي (prototype) يسمح لك باستخدام أي دالة مقارنة فرعية # كدالة ترتيب فرعية (بما في ذلك الدوال الفرعية للحزم الأخرى) 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; # ضمان الاستقرار use sort 'stable'; my @new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @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).
- splice ARRAY,OFFSET,LENGTH,LIST
- splice ARRAY,OFFSET,LENGTH
- splice ARRAY,OFFSET
- splice ARRAY
- يزيل
العناصر
المحددة
بواسطة 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/
- split
- يقسم
السلسلة
النصية 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 هو "/^/"، فسيُعامل كما لو أنه استخدم معدل تعدد الأسطر ("/^/m")، بما أنه ليس ذا فائدة تذكر بخلاف ذلك.
يمكن تحديد "/m" وأي من معدلات الأنماط الأخرى الصالحة لـ "qr" (الملخصة في "qr/STRING/msixpodualn" في perlop) بشكل صريح.
كحالة خاصة أخرى، يحاكي "split" السلوك المبدئي لأداة سطر الأوامر 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'". في الإصدارات السابقة، وخارج نطاق تلك الميزة، فإنه يظهر "The Unicode Bug" المذكورة في perlunicode: حيث يمكن معاملة الأحرف التي تعتبر مسافات بيضاء وفقًا لقواعد Unicode ولكن ليس وفقًا لقواعد 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") - sprintf FORMAT, LIST
- يعيد سلسلة
نصية منسقة
حسب
اصطلاحات
"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" - flags
- واحد أو
أكثر من:
مسافة سابقة للأرقام غير السالبة بمسافة + سابقة للأرقام غير السالبة بعلامة زائد - محاذاة إلى اليسار داخل الحقل 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
- sqrt
- تُرجع
الجذر
التربيعي
الموجب لـ EXPR.
إذا تم حذف
EXPR، تستخدم
$_. تعمل
فقط مع
المعاملات
غير
السالبة ما
لم تكن قد
قمت بتحميل
وحدة
"Math::Complex".
use Math::Complex; print sqrt(-4); # يطبع 2i - srand EXPR
- srand
- تضبط
وتُرجع
بذرة
الأرقام
العشوائية
لمعامل
"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" ليست آمنة تعموياً. يجب ألا تعتمد عليها في المواقف الحساسة أمنياً. حتى وقت كتابة هذا الدليل، توفر عدة وحدات CPAN من جهات خارجية مولدات أرقام عشوائية يقصد مؤلفوها أن تكون آمنة تعموياً، بما في ذلك: Data::Entropy، و Crypt::Random، و Math::Random::Secure، و Math::TrulyRandom.
- stat FILEHANDLE
- stat EXPR
- stat DIRHANDLE
- stat
- تُرجع
قائمة من 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، ولكن بالنسبة للأول # غالباً ما يكون معامل -g مكافئاً. ENFMT ترمز إلى # فرض قفل السجلات، وهي ميزة تعتمد على المنصة. S_ISENFMT($mode) S_ISWHT($mode)راجع وثائق chmod(2) و stat(2) الأصلية لمزيد من التفاصيل حول ثوابت "S_I*". للحصول على معلومات الحالة لوصلة رمزية بدلاً من الملف الهدف وراء الوصلة، استخدم دالة "lstat".
قضايا المحمولية: "stat" في perlport.
- state VARLIST
- state TYPE VARLIST
- state VARLIST : ATTRS
- state TYPE VARLIST : ATTRS
- تُصرح
"state" عن
متغير ذو
نطاق
معجمي،
تماماً مثل
"my". ومع
ذلك، لن يتم
إعادة
تهيئة هذه
المتغيرات
أبداً، على
عكس
المتغيرات
المعجمية
التي تُعاد
تهيئتها في
كل مرة يتم
فيها
الدخول إلى
الكتلة
المحيطة
بها. انظر
"المتغيرات
الخاصة
المستمرة"
في perlsub لمزيد
من
التفاصيل.
إذا تم سرد أكثر من متغير واحد، فيجب وضع القائمة بين قوسين. مع القائمة المقوسة، يمكن استخدام "undef" كمكان حجز وهمي. ومع ذلك، بما أن تهيئة متغيرات الحالة في مثل هذه القوائم غير ممكن حالياً، فلن يخدم هذا أي غرض.
مثل "my" و "local" و "our"، يمكن لـ "state" أن تعمل على متغير أينما ظهر في تعبير (بصرف النظر عن الاستيفاء في السلاسل النصية). لن ينطبق التصريح على الاستخدامات الإضافية لنفس المتغير حتى الجملة التالية. هذا يعني أن الاستخدامات الإضافية لهذا المتغير ضمن نفس الجملة ستتصرف كما كانت ستفعل قبل حدوث هذا التصريح، أو ستؤدي إلى خطأ '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
- في هذا
الوقت، لا
تفعل "study"
شيئاً. قد
يتغير هذا
في
المستقبل.
قبل الإصدار 5.16 من Perl، كانت تقوم بإنشاء فهرس مقلوب لجميع المحارف التي ظهرت في SCALAR المعطى (أو $_ إذا لم يُحدد). عند مطابقة نمط، كان يتم البحث عن أندر محرف في النمط في هذا الفهرس. كانت الندرة تعتمد على بعض جداول التكرار الثابتة التي تم إنشاؤها من بعض برامج C والنصوص الإنجليزية.
- sub NAME BLOCK
- sub NAME (PROTO) BLOCK
- sub NAME : ATTRS BLOCK
- sub NAME (PROTO) : ATTRS BLOCK
- هذا تعريف
روتين
فرعي، وليس
دالة
حقيقية في
حد ذاتها.
بدون BLOCK فهو
مجرد تصريح
مسبق. وبدون
NAME، فهو
تصريح
لدالة
مجهولة،
لذا فهي
تُرجع قيمة:
مرجع الكود
(CODE ref)
للانغلاق (closure)
الذي تم
إنشاؤه
للتو.
انظر perlsub و perlref للحصول على تفاصيل حول الروتينات الفرعية والمراجع؛ انظر attributes و Attribute::Handlers لمزيد من المعلومات حول السمات.
- __SUB__
- وسم خاص
يُرجع
مرجعاً
للروتين
الفرعي
الحالي، أو
"undef" خارج
الروتين
الفرعي.
سلوك "__SUB__" داخل كتلة كود تعبير نمطي (مثل "/(?{...})/") عرضة للتغيير.
هذا الوسم متاح فقط تحت "use v5.16" أو ميزة "current_sub". انظر feature.
- substr EXPR,OFFSET,LENGTH,REPLACEMENT
- substr EXPR,OFFSET,LENGTH
- substr EXPR,OFFSET
- تستخرج
سلسلة نصية
فرعية من 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" تُرجع القيمة غير المعرفة وتُصدر تحذيراً. عند استخدامها كقيمة يسارية، فإن تحديد سلسلة فرعية تقع بالكامل خارج السلسلة يثير استثناءً. فيما يلي مثال يوضح السلوك للحالات الحدية:
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"لاحظ أن القيمة اليسارية المرتجعة بواسطة إصدار الوسائط الثلاثة من "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، كانت النتيجة مع الإزاحات السالبة غير محددة.
- symlink OLDFILE,NEWFILE
- تنشئ اسم
ملف جديداً
موصولاً
رمزياً
باسم الملف
القديم.
تُرجع 1
للنجاح، و
0 غير
ذلك. في
الأنظمة
التي لا
تدعم
الوصلات
الرمزية،
تثير
استثناءً.
للتحقق من
ذلك،
استخدم eval:
my $symlink_exists = eval { symlink("",""); 1 };مسائل قابلية النقل: "symlink" في perlport.
- syscall NUMBER, LIST
- يستدعي
نداء
النظام
المحدد
كعنصر أول
في
القائمة،
مع تمرير
العناصر
المتبقية
كمعاملات
لنداء
النظام.
يُرفع
استثناء
إذا كان غير
منفذ. تُفسر
المعاملات
كما يلي:
إذا كان
المعامل
المعطى
عدديًا،
يُمرر
المعامل
كعدد صحيح (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.
- sysopen FILEHANDLE,FILENAME,MODE
- sysopen FILEHANDLE,FILENAME,MODE,PERMS
- يفتح الملف
الذي اسمه
FILENAME، ويربطه
بـ FILEHANDLE. إذا
كان FILEHANDLE
تعبيرًا،
تُستخدم
قيمته
كمقبض ملف
حقيقي
مطلوب؛
وسيُخلق
المتغير
القياسي
غير المعرف
آليًا بشكل
مناسب.
تستدعي هذه
الدالة
وظيفة 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" في العديد من الأنظمة لفتح الملفات في الوضع الحصري. هذا ليس قفلًا: الحصرية هنا تعني أنه إذا كان الملف موجودًا بالفعل، فإن "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.
- sysread FILEHANDLE,SCALAR,LENGTH,OFFSET
- sysread FILEHANDLE,SCALAR,LENGTH
- تحاول
قراءة LENGTH
بايت من
البيانات
في المتغير
SCALAR من مقبض
الملف
المحدد FILEHANDLE،
باستخدام
read(2). وهي
تتجاوز أي
طبقات PerlIO بما
في ذلك
الإدخال
والإخراج
المخبأ
(لكنها
تتأثر
بوجود طبقة
":utf8" كما
هو موضح
لاحقًا)،
لذا فإن خلط
هذا مع
أنواع أخرى
من
القراءات،
أو "print"
أو "write"
أو "seek" أو
"tell" أو
"eof" يمكن
أن يسبب
ارتباكًا
لأن طبقات
":perlio" أو
":crlf" تقوم
عادةً
بتخزين
البيانات
مؤقتًا.
تعيد عدد
البايتات
التي تمت
قراءتها
بالفعل، أو
0 عند
نهاية
الملف، أو undef
إذا كان
هناك خطأ
(في الحالة
الأخيرة
يتم ضبط
$! أيضًا).
سيتم تكبير
أو تصغير SCALAR
بحيث يكون
آخر بايت تم
قراءته
فعليًا هو
آخر بايت في
المتغير
القياسي
بعد
القراءة.
يمكن تحديد OFFSET لوضع البيانات المقروءة في مكان ما في السلسلة غير البداية. تحدد الإزاحة OFFSET السالبة الموضع بعدد من المحارف بالعد تنازلياً من نهاية السلسلة. أما الإزاحة OFFSET الموجبة الأكبر من طول SCALAR فتؤدي إلى حشو السلسلة إلى الحجم المطلوب ببايتات "\0" قبل إلحاق نتيجة القراءة.
لا توجد دالة syseof()، وهذا أمر جيد، لأن "eof" لا تعمل جيدًا على ملفات الأجهزة (مثل ttys) على أي حال. استخدم "sysread" وتحقق من القيمة المعادة 0 لتحديد ما إذا كنت قد انتهيت.
لاحظ أنه إذا تم وسم مقبض الملف كـ ":utf8"، فإن "sysread" سترفع استثناءً. طبقة :encoding(...) تقدم ضمنيًا طبقة ":utf8". انظر "binmode" و "open" و open pragma.
- sysseek FILEHANDLE,POSITION,WHENCE
- يضبط موضع
نظام 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" تعيد صحيحًا عند النجاح وخطأ عند الفشل، ومع ذلك لا يزال بإمكانك بسهولة تحديد الموضع الجديد.
- system LIST
- system PROGRAM LIST
- تقوم بنفس
ما تقوم به
"exec"
بالضبط،
إلا أنه يتم
إجراء
تفريع (fork)
أولاً
وتنتظر
العملية
الأب خروج
العملية
الابن. لاحظ
أن معالجة
المعاملات
تختلف
اعتمادًا
على عدد
المعاملات.
إذا كان
هناك أكثر
من معامل
واحد في LIST،
أو إذا كانت
LIST مصفوفة
تحتوي على
أكثر من
قيمة
واحدة،
يبدأ
البرنامج
المعطى
بالعنصر
الأول من
القائمة مع
المعاملات
المعطاة
ببقية
القائمة.
إذا كان
هناك معامل
قياسي واحد
فقط، يتم
فحص
المعامل
بحثًا عن
محارف
الصدفة
الوصفية
(metacharacters)، وإذا
وجد أي
منها، يتم
تمرير
المعامل
بالكامل
إلى صدفة
أوامر
النظام
لتحليله
(هذا هو "/bin/sh
-c" على
منصات Unix،
ولكنه
يختلف في
المنصات
الأخرى).
إذا لم تكن
هناك محارف
صدفة وصفية
في
المعامل،
يتم تقسيمه
إلى كلمات
وتمريره
مباشرة إلى
"execvp"،
وهو أمر
أكثر كفاءة.
في Windows، وحدها
صيغة "system PROGRAM
LIST" ستتجنب
استخدام
الصدفة
بشكل
موثوق؛ أما
"system LIST"،
حتى مع وجود
أكثر من
عنصر واحد،
فسوف
تتراجع إلى
الصدفة إذا
فشلت عملية
التوليد
الأولى.
ستحاول Perl تفريغ جميع الملفات المفتوحة للإخراج قبل أي عملية قد تقوم بـ fork، ولكن قد لا يكون هذا مدعومًا في بعض المنصات (راجع perlport). لتكون آمنًا، قد تحتاج إلى ضبط $| (أو $AUTOFLUSH بالإنجليزية) أو استدعاء تابع "autoflush" الخاص بـ "IO::Handle" على أي مقابض مفتوحة.
القيمة المعادة هي حالة خروج البرنامج كما أرجعها نداء "wait". للحصول على قيمة الخروج الفعلية، أزح لليمين بمقدار ثمانية (انظر أدناه). انظر أيضًا "exec". هذا ليس ما تريد استخدامه لالتقاط المخرجات من أمر ما؛ لذلك يجب عليك استخدام علامات الاقتباس الخلفية (backticks) أو "qx//"، كما هو موضح في "`STRING`" في perlop. تشير القيمة المعادة -1 إلى فشل في بدء البرنامج أو خطأ في نداء النظام wait(2) (افحص $! لمعرفة السبب).
إذا كنت ترغب في جعل "system" (وأجزاء أخرى كثيرة من Perl) تتوقف عند حدوث خطأ، فراجع autodie pragma.
مثل "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.
- syswrite FILEHANDLE,SCALAR,LENGTH,OFFSET
- syswrite FILEHANDLE,SCALAR,LENGTH
- syswrite FILEHANDLE,SCALAR
- تحاول
كتابة 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
- tell
- تعيد
الموضع
الحالي
بالبايتات
لـ 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" ذلك.
- telldir DIRHANDLE
- تعيد الموضع الحالي لروتينات "readdir" على DIRHANDLE. يمكن إعطاء القيمة لـ "seekdir" للوصول إلى موقع معين في دليل. تخضع "telldir" لنفس المحاذير بشأن ضغط الدليل المحتمل مثل روتين مكتبة النظام المقابل.
- tie VARIABLE,CLASSNAME,LIST
- تربط هذه
الدالة
متغيرًا
بفئة حزمة
ستوفر
التنفيذ
للمتغير. 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".
- tied VARIABLE
- تعيد مرجعًا للكائن الأساسي لـ VARIABLE (نفس القيمة التي تم إرجاعها في الأصل بواسطة نداء "tie" الذي ربط المتغير بحزمة). تعيد القيمة غير المعرفة إذا كان VARIABLE غير مربوط بحزمة.
- time
- تعيد عدد
الثواني
غير
الكبيسة
منذ الوقت
الذي
يعتبره
النظام
حقبة (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.
- tr///
- معامل حرفنة النصوص (transliteration). هو نفسه "y///". انظر "Quote-Like Operators" في perlop.
- truncate FILEHANDLE,LENGTH
- truncate EXPR,LENGTH
- يقلص الملف
المفتوح
على FILEHANDLE، أو
المسمى
بواسطة EXPR،
إلى الطول
المحدد.
يرفع
استثناءً
إذا كان
التقليص (truncate)
غير منفذ في
نظامك. يعيد
صحيحًا إذا
نجح، و
"undef" عند
حدوث خطأ.
السلوك غير محدد إذا كان LENGTH أكبر من طول الملف.
يُترك موضع FILEHANDLE في الملف دون تغيير. قد ترغب في استدعاء seek قبل الكتابة في الملف.
مسائل قابلية النقل: "truncate" في perlport.
- uc EXPR
- uc
- تعيد نسخة
من 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
- ucfirst
- تعيد قيمة 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
- تضبط umask
للعملية
على EXPR وتعيد
القيمة
السابقة.
إذا تم حذف
EXPR، تعيد umask
الحالية
فحسب.
تُمثل صلاحيات Unix المسماة "rwxr-x---" في ثلاث مجموعات من ثلاثة بتات، أو ثلاثة أرقام ثمانية: 0750 (الصفر البادئ يشير إلى النظام الثماني وليس واحدًا من الأرقام). قيمة "umask" هي رقم يمثل بتات الصلاحيات المعطلة. قيم الصلاحيات (أو "الوضع") التي تمررها لـ "mkdir" أو "sysopen" تُعدل بواسطة umask، لذا حتى لو أخبرت "sysopen" بإنشاء ملف بصلاحيات 0777، وكان umask الخاص بك هو 0022، فسيتم إنشاء الملف فعليًا بصلاحيات 0755. إذا كان "umask" هو 0027 (المجموعة لا يمكنها الكتابة؛ والآخرون لا يمكنهم القراءة أو الكتابة أو التنفيذ)، فإن تمرير 0666 لـ "sysopen" سيؤدي لإنشاء ملف بوضع 0640 (لأن "0666 &~ 027" هو 0640).
إليك بعض النصائح: قدم وضع إنشاء بقيمة 0666 للملفات العادية (في "sysopen") ووضع 0777 للأدلة (في "mkdir") والملفات القابلة للتنفيذ. هذا يعطي المستخدمين حرية الاختيار: إذا أرادوا ملفات محمية، فيمكنهم اختيار umasks للعملية بقيم مثل 022 أو 027 أو حتى القناع الانعزالي للغاية 077. نادرًا ما ينبغي للبرامج اتخاذ قرارات سياساتية يُفضل تركها للمستخدم. الاستثناء من ذلك هو عند كتابة ملفات يجب أن تظل خاصة: ملفات البريد، ملفات تعريف ارتباط متصفح الويب، ملفات .rhosts، وما إلى ذلك.
إذا كان umask(2) غير منفذ في نظامك وكنت تحاول تقييد الوصول لنفسك (أي، "(EXPR & 0700) > 0")، يتم رفع استثناء. إذا كان umask(2) غير منفذ ولم تكن تحاول تقييد الوصول لنفسك، تعيد "undef".
تذكر أن umask هو رقم، وعادة ما يُعطى بالنظام الثماني؛ وليس سلسلة من الأرقام الثمانية. انظر أيضًا "oct"، إذا كان كل ما تملكه هو سلسلة نصية.
مسائل قابلية النقل: "umask" في perlport.
- undef EXPR
- undef
- تزيل تعريف
قيمة 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
- unlink
- تحذف قائمة
من الملفات.
عند
النجاح،
تعيد عدد
الملفات
التي
حذفتها
بنجاح. وعند
الفشل،
تعيد خطأ
وتضبط $!
(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 TEMPLATE,EXPR
- unpack TEMPLATE
- تقوم
"unpack"
بعكس ما
تفعله
"pack": فهي
تأخذ سلسلة
نصية
وتوسعها
إلى قائمة
من القيم.
(في سياق
عددي،
تُرجع
القيمة
الأولى
الناتجة
فقط.)
إذا أُسقط التعبير EXPR، تُفك السلسلة النصية $_. انظر perlpacktut للحصول على مقدمة عن هذه الدالة.
تُجزأ السلسلة النصية إلى مقاطع يصفها القالب TEMPLATE. يُحول كل مقطع بشكل منفصل إلى قيمة. عادةً ما تكون السلسلة إما نتيجة لـ "pack"، أو تمثل محارف السلسلة بنية C من نوع ما.
للقالب TEMPLATE التنسيق نفسه المستخدم في دالة "pack". إليك روتين فرعي يقوم بعملية اقتطاع السلسلة (substring):
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" بحذر. بما أنه لا توجد وسيلة في بيرل للتحقق مما إذا كانت القيمة الممررة إلى "unpack" تقابل موقعاً صالحاً في الذاكرة، فإن تمرير قيمة مؤشر غير معروفة الصلاحية قد يؤدي إلى عواقب كارثية.
إذا كان هناك المزيد من رموز الحزم أو إذا كان عدد مرات التكرار لحقل أو مجموعة أكبر مما تسمح به بقية سلسلة الإدخال، فإن النتيجة غير محددة جيداً: قد يُقلل عدد مرات التكرار، أو قد تُنتج "unpack" سلاسل فارغة أو أصفاراً، أو قد تثير استثناءً. إذا كانت سلسلة الإدخال أطول مما يصفه القالب TEMPLATE، فتُتجاهل بقية سلسلة الإدخال تلك.
انظر "pack" لمزيد من الأمثلة والملاحظات.
- unshift ARRAY,LIST
- يضيف
عنصراً
واحداً أو
أكثر إلى
بداية
المصفوفة.
وهذا عكس
عملية
"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.
- untie VARIABLE
- يفك الارتباط بين متغير وحزمة ما. (انظر tie.) ليس له أي تأثير إذا لم يكن المتغير مرتبطاً (tied).
- use Module VERSION LIST
- use Module VERSION
- use Module LIST
- use Module
- يستورد بعض
الدلالات
(semantics) إلى
الحزمة
الحالية من
الوحدة
المسماة،
عادةً عن
طريق تعيين
أسماء
مستعارة
لروتينات
فرعية أو
متغيرات
معينة في
حزمتك. إنه
يعادل
تماماً
BEGIN { require Module; Module->import( LIST ); }إلا أن Module يجب أن يكون كلمة صريحة (bareword). يمكن جعل الاستيراد مشروطاً باستخدام وحدة if.
تفرض "BEGIN" تنفيذ "require" و "import" وقت التصريف. تتأكد "require" من تحميل الوحدة في الذاكرة إذا لم تُحمل بعد. دالة "import" ليست دالة مدمجة؛ بل هي مجرد استدعاء أسلوب (method) ساكن عادي في حزمة "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 sigtrap qw(SEGV BUS); use strict qw(subs vars refs); use subs qw(afunc blurfl); use warnings qw(all); use sort qw(stable);تستورد بعض هذه الوحدات الوهمية دلالات في نطاق الكتلة الحالي (مثل "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، أو قائمة مسقطة أو فارغة، أو عند عدم العثور على أسلوب unimport.
no integer; no strict 'refs'; no warnings;انظر perlmodlib للحصول على قائمة بالوحدات والتعليمات القياسية. انظر perlrun لخيارات سطر الأوامر "-M" و "-m" لبيرل التي تمنح وظائف "use" من سطر الأوامر.
- use VERSION
- يُفعل
معجمياً كل
الميزات
المتاحة في
الإصدار
المطلوب
كما تحددها
تعليمة 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غالباً ما يكون هذا مفيداً إذا كنت بحاجة إلى التحقق من إصدار بيرل الحالي قبل "use" (استخدام) وحدات المكتبة التي لن تعمل مع إصدارات أقدم من بيرل. (نحاول ألا نفعل ذلك أكثر مما يجب.)
بشكل متماثل، تسمح لك "no VERSION" بتحديد أنك تريد إصداراً من بيرل أقدم من الإصدار المحدد. تاريخياً، أضيفت هذه الميزة أثناء التصميمات المبكرة للغة راكو (المعروفة سابقاً بـ "بيرل 6")، بحيث يمكن لبرنامج بيرل 5 أن يبدأ بـ
no 6;للإعلان عن أنه ليس برنامج بيرل 6. وبما أن اللغتين لهما تنفيذات مختلفة، واصطلاحات تسمية ملفات، وبنية تحتية أخرى، فإن هذه الميزة قليلة الاستخدام الآن في الممارسة العملية وينبغي تجنبها في الكود المكتوب حديثاً.
يجب توخي الحذر عند استخدام صيغة "no VERSION"، لأنها فقط تهدف إلى التأكيد على أن بيرل الذي يعمل هو إصدار أقدم من وسيطتها وليس للتراجع عن الآثار الجانبية لتمكين الميزات الخاصة بـ "use VERSION".
- utime LIST
- يغير وقت
الوصول
ووقت
التعديل
لكل ملف في
قائمة
الملفات.
يجب أن يكون
أول عنصرين
في القائمة
هما أوقات
الوصول
والتعديل
الرقمية،
بهذا
الترتيب.
تُرجع عدد
الملفات
التي غُيرت
بنجاح.
يُضبط وقت
تغيير inode لكل
ملف على
الوقت
الحالي. على
سبيل
المثال،
هذا الكود
له مفعول
أمر touch(1) في
يونكس نفسه
عندما تكون
الملفات
موجودة
بالفعل
وتخص
المستخدم
الذي يقوم
بتشغيل
البرنامج:
#!/usr/bin/perl my $atime = my $mtime = time; utime $atime, $mtime, @ARGV;منذ إصدار بيرل 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) أو مراجع أنماط عمومية ليتعرف عليها؛ أما الكلمات الصريحة (barewords) فتُعتبر أسماء ملفات.
قضايا القابلية للنقل: "utime" في perlport.
- values HASH
- values ARRAY
- في سياق
قائمة،
تُرجع
قائمة
تتكون من
جميع قيم
الهاش (hash)
المسمى. في
إصدار بيرل
5.12 أو أحدث
فقط،
ستُرجع
أيضاً
قائمة بقيم
المصفوفة؛
قبل هذا
الإصدار،
كانت
محاولة
استخدام
وسيطة
مصفوفة
تنتج خطأ في
الصياغة. في
السياق
العددي،
تُرجع عدد
القيم.
تُرجع مدخلات الهاش بترتيب يبدو عشوائياً. الترتيب العشوائي الفعلي خاص بكل هاش؛ فنفس سلسلة العمليات على هاشين قد تؤدي إلى ترتيب مختلف لكل منهما. أي عملية إدراج في الهاش قد تغير الترتيب، وكذلك أي عملية حذف، باستثناء أن آخر مفتاح أُرجع بواسطة "each" أو "keys" يمكن حذفه دون تغيير الترتيب. وطالما أن هاشاً معيناً لم يُعدل، يمكنك الاعتماد على "keys" و "values" و "each" لإرجاع نفس الترتيب بشكل متكرر. انظر "هجمات التعقيد الخوارزمي" في perlsec للحصول على تفاصيل حول سبب عشوائية ترتيب الهاش. وبصرف النظر عن الضمانات المقدمة هنا، فإن التفاصيل الدقيقة لخوارزمية الهاش في بيرل وترتيب التنقل في الهاش عرضة للتغيير في أي إصدار من بيرل. الهاشات المرتبطة (Tied hashes) قد تتصرف بشكل مختلف عن هاشات بيرل فيما يتعلق بتغيرات الترتيب عند إدراج وحذف العناصر.
كأثر جانبي، يؤدي استدعاء "values" إلى إعادة ضبط المكرر الداخلي للهاش أو المصفوفة (انظر "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".
- vec EXPR,OFFSET,BITS
- يعامل
السلسلة
النصية في 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"لتحويل متجهة بتات إلى سلسلة أو قائمة من 0 و 1، استخدم هذه:
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
- يسلك سلوك
wait(2) على
نظامك: حيث
ينتظر
انتهاء
عملية
وليدة
ويعيد معرف
العملية (pid)
للعملية
المنتهية،
أو -1 إذا
لم يكن هناك
عمليات
وليدة.
تُعاد
الحالة في
$? و
"${^CHILD_ERROR_NATIVE}".
لاحظ أن
قيمة
الإعادة
-1 قد
تعني أن
العمليات
الوليدة
تُحصد
آليًا، كما
هو موضح في
perlipc.
إذا استخدمت "wait" في معالجك لـ $SIG{CHLD}، فقد ينتظر عن طريق الخطأ العملية الوليدة المنشأة بواسطة "qx" أو "system". راجع perlipc للتفاصيل.
يكافئ "waitpid(-1, 0)".
قضايا قابلية النقل: "wait" في perlport.
- waitpid PID,FLAGS
- ينتظر
انتهاء
عملية
وليدة
معينة
ويعيد معرف
العملية (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.
- wantarray
- تعيد 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() بدلاً من ذلك.
- warn LIST
- تطلق
تحذيرًا،
عادةً عن
طريق
طباعته إلى
"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
- write
- تكتب سجلاً
منسقًا
(ربما متعدد
الأسطر) إلى
FILEHANDLE المحدد،
باستخدام
التنسيق
المرتبط
بهذا الملف.
مبدئيًا،
التنسيق
الخاص بملف
هو التنسيق
الذي يحمل
نفس اسم
مقبض
الملف،
ولكن يمكن
ضبط تنسيق
قناة
الإخراج
الحالية
(انظر دالة
"select")
صراحةً عن
طريق تعيين
اسم
التنسيق
إلى
المتغير
$~.
تتم معالجة بداية النموذج آليًا: إذا لم تكن هناك مساحة كافية في الصفحة الحالية للسجل المنسق، فتُقدم الصفحة عن طريق كتابة تغذية نموذج (form feed) ويُستخدم تنسيق خاص لبداية الصفحة لتنسيق ترويسة الصفحة الجديدة قبل كتابة السجل. مبدئيًا، تنسيق بداية الصفحة هو اسم مقبض الملف مع إلحاق "_TOP" به، أو "top" في الحزمة الحالية إذا لم يكن الأول موجودًا. قد يمثل هذا مشكلة مع مقابض الملفات الحية تلقائيًا (autovivified)، ولكن يمكن ضبطه ديناميكيًا على التنسيق الذي تختاره عن طريق تعيين الاسم للمتغير $^ أثناء تحديد مقبض الملف هذا. عدد الأسطر المتبقية في الصفحة الحالية موجود في المتغير "$-"، والذي يمكن ضبطه على 0 لفرض صفحة جديدة.
إذا لم يُحدد FILEHANDLE، يذهب الإخراج إلى قناة الإخراج المبدئية الحالية، والتي تبدأ كـ STDOUT ولكن يمكن تغييرها بواسطة عامل "select". إذا كان FILEHANDLE عبارة عن EXPR، فتُقيم التعبير وتُستخدم السلسلة الناتجة للبحث عن اسم FILEHANDLE في وقت التشغيل. لمزيد من المعلومات حول التنسيقات، انظر perlform.
لاحظ أن write ليست عكس "read". لسوء الحظ.
- y///
- عامل الترجمة الحرفية (transliteration). هو نفسه "tr///". انظر "Quote-Like Operators" في perlop.
الكلمات المفتاحية غير الدالية حسب الإحالة المرجعية¶
perldata
- __DATA__
- __END__
- هذه الكلمات المفتاحية موثقة في "Special Literals" في perldata.
perlmod
- BEGIN
- CHECK
- النهاية
- INIT
- UNITCHECK
- هذه الكلمات المفتاحية لمرحلة التصريف (compile phase) موثقة في "BEGIN, UNITCHECK, CHECK, INIT and END" في perlmod.
perlobj
- DESTROY
- الكلمة المفتاحية لهذه الطريقة (method) موثقة في "Destructors" في perlobj.
perlop
perlsub
- AUTOLOAD
- هذه الكلمة المفتاحية موثقة في "Autoloading" في perlsub.
perlsyn
- else
- elsif
- لـ
- foreach
- if
- unless
- until
- while
- كلمات التحكم في التدفق (flow-control) هذه موثقة في "Compound Statements" في perlsyn.
- elseif
- تُكتب
الكلمة
المفتاحية
"else if" في لغة Perl
بصيغة
"elsif". لا
توجد "elif"
أو "else if"
أيضاً. إنها
تقوم
بتحليل
"elseif"،
ولكن فقط
لتحذيرك من
عدم
استخدامها.
انظر توثيق كلمات التحكم في التدفق في "Compound Statements" في perlsyn.
- default
- given
- when
- كلمات التحكم في التدفق هذه المتعلقة بميزة التحويل (switch) التجريبية موثقة في "Switch Statements" في perlsyn.
- try
- catch
- finally
- كلمات التحكم في التدفق هذه المتعلقة بميزة "try" التجريبية موثقة في "Try Catch Exception Handling" في perlsyn.
- defer
- الكلمة المفتاحية للتحكم في التدفق هذه المتعلقة بميزة "defer" التجريبية موثقة في "defer blocks" في perlsyn.
- ADJUST
- كتلة phaser المتعلقة بالفئة (class) هذه موثقة في perlclass.
ترجمة¶
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>
هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.
إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.
| 16 نوفمبر 2025 | بيرل v5.40.1 |