Scroll to navigation

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

الاسم

perldata - أنواع بيانات بيرل

الوصف

أسماء المتغيرات

تمتلك بيرل ثلاثة أنواع بيانات مدمجة: السكالار (scalars)، ومصفوفات السكالار، والمصفوفات الترابطية للسكالار، المعروفة باسم "hashes". السكالار هو سلسلة نصية واحدة (بأي حجم، محدودة فقط بالذاكرة المتاحة)، أو رقم، أو مرجع لشيء ما (سيُنقش في perlref). المصفوفات العادية هي قوائم مرتبة من السكالار مفهرسة بالأرقام، بدءًا من 0. الـ Hashes هي مجموعات غير مرتبة من قيم السكالار مفهرسة بمفتاح نصي مرتبط بها.

يُشار إلى القيم عادةً بالاسم، أو من خلال مرجع مسمى. يخبرك الحرف الأول من الاسم بنوع هيكل البيانات الذي يشير إليه. ويخبرك بقية الاسم بالقيمة المحددة التي يشير إليها. عادةً ما يكون هذا الاسم عبارة عن identifier (مُعرف) واحد، أي سلسلة نصية تبدأ بحرف أو شرطة سفلية، وتحتوي على حروف وشرطات سفلية وأرقام. في بعض الحالات، قد يكون سلسلة من المعرفات، مفصولة بـ "::" (أو بـ "'" المهجورة)؛ وتُفسر جميعها باستثناء الأخير كألسماء حزم، لتحديد مساحة الأسماء التي يجب البحث فيها عن المعرف النهائي (راجع "Packages" في perlmod للتفاصيل). لمناقشة أكثر عمقًا حول المعرفات، راجع "Identifier parsing". من الممكن استبدال المعرف البسيط بتعبير ينتج مرجعًا للقيمة في وقت التشغيل. هذا موصوف بمزيد من التفصيل أدناه وفي perlref.

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

تُسمى قيم السكالار دائمًا بـ '$'، حتى عند الإشارة إلى سكالار هو جزء من مصفوفة أو hash. يعمل الرمز '$' دلاليًا مثل كلمة التعريف في اللغة الإنجليزية من حيث أنه يشير إلى توقع قيمة واحدة.

    $days               # قيمة السكالار البسيطة "days"
    $days[28]           # العنصر 29 في المصفوفة @days
    $days{'Feb'}        # القيمة المقابلة لـ 'Feb' من الـ hash %days
    $#days              # الفهرس الأخير للمصفوفة @days

يُشار إلى المصفوفات بأكملها (وشرائح المصفوفات والـ hashes) بـ '@'، وهو ما يعمل تمامًا مثل كلمات الجمع في الإنجليزية، حيث يشير إلى أنه يُتوقع قيم متعددة.

    @days               # ($days[0], $days[1],... $days[n])
    @days[3,4,5]        # تكافئ ($days[3],$days[4],$days[5])
    @days{'a','c'}      # تكافئ ($days{'a'},$days{'c'})

يُشار إلى الـ hashes بأكملها بـ '%':

    %days               # (مفتاح1، قيمة1، مفتاح2، قيمة2 ...)

بالإضافة إلى ذلك، تُسمى الروتينات الفرعية بـ '&' في بدايتها، رغم أن هذا اختياري عندما لا يكون هناك غموض. يمكن تسمية إدخالات جدول الرموز بـ '*' في بدايتها، لكنك لا تهتم بذلك حقًا بعد (إن كنت ستهتم أصلًا :-).

كل نوع متغير له مساحة أسماء خاصة به، وكذلك العديد من المعرفات غير المتغيرة. هذا يعني أنه يمكنك، دون خوف من التعارض، استخدام نفس الاسم لمتغير سكالار، أو مصفوفة، أو hash -- أو حتى لمقبض ملف، أو مقبض دليل، أو اسم روتين فرعي، أو اسم تنسيق، أو وسم. هذا يعني أن $foo و @foo هما متغيران مختلفان. ويعني أيضًا أن $foo[1] هو جزء من @foo، وليس جزءًا من $foo. قد يبدو هذا غريبًا بعض الشيء، لكن لا بأس، لأنه غريب فعلاً.

بما أن مراجع المتغيرات تبدأ دائمًا بـ '$' أو '@' أو '%'، فإن الكلمات "المحجوزة" ليست محجوزة فعليًا فيما يتعلق بأسماء المتغيرات. ومع ذلك، فهي محجوزة فيما يتعلق بالوسوم ومقابض الملفات، التي لا تحتوي على حرف خاص في بدايتها. لا يمكنك الحصول على مقبض ملف باسم "log"، على سبيل المثال. تلميح: يمكنك قول "open(LOG,'logfile')" بدلاً من "open(log,'logfile')". كما أن استخدام الحروف الكبيرة لمقابض الملفات يحسن من قابلية القراءة ويحميك من التعارض مع الكلمات المحجوزة مستقبلاً. حالة الأحرف مهمة -- "FOO" و "Foo" و "foo" كلها أسماء مختلفة. الأسماء التي تبدأ بحرف أو شرطة سفلية قد تحتوي أيضًا على أرقام وشرطات سفلية.

من الممكن استبدال مثل هذا الاسم الأبجدي الرقمي بتعبير يعيد مرجعًا للنوع المناسب. لوصف هذا، راجع perlref.

الأسماء التي تبدأ برقم قد تحتوي فقط على مزيد من الأرقام. الأسماء التي لا تبدأ بحرف، أو شرطة سفلية، أو رقم، أو علامة أقحوان (caret) تقتصر على حرف واحد، مثل $% أو $$. (معظم هذه الأسماء ذات الحرف الواحد لها أهمية محددة مسبقًا لبيرل. على سبيل المثال، $$ هو معرف العملية الحالية. وجميع هذه الأسماء محجوزة لاستخدام بيرل المحتمل).

تحليل المعرف

حتى الإصدار 5.18 من بيرل، كانت القواعد الفعلية لما يشكل معرفًا صالحًا غامضة قليلاً. ومع ذلك، وبشكل عام، فإن أي شيء مُعرف هنا يجب أن يعمل في الإصدارات السابقة من بيرل، بينما العكس -- الحالات الحدية التي تعمل في الإصدارات السابقة ولكنها غير معرفة هنا -- فمن المحتمل ألا تعمل في الإصدارات الأحدث. كملاحظة جانبية هامة، يُرجى ملاحظة أن ما يلي ينطبق فقط على معرفات bareword الموجودة في كود مصدر بيرل، وليس المعرفات المقدمة من خلال المراجع الرمزية، والتي لديها قيود أقل بكثير. إذا كنت تعمل تحت تأثير توجيه "use utf8;"، فستنطبق القواعد التالية:

    / (?[ ( \p{Word} & \p{XID_Start} ) + [_] ])
      (?[ ( \p{Word} & \p{XID_Continue} ) ]) *    /x

أي، حرف "بداية" متبوع بأي عدد من حروف "الاستمرار". تطلب بيرل أن يطابق كل حرف في المعرف أيضًا "\w" (هذا يمنع بعض الحالات الإشكالية)؛ كما تقبل بيرل بالإضافة إلى ذلك أسماء المعرفات التي تبدأ بشرطة سفلية.

إذا لم يكن تحت "use utf8"، فسيُعامل المصدر على أنه ASCII + 128 حرفًا عامًا إضافيًا، ويجب أن تطابق المعرفات

    / (?aa) (?!\d) \w+ /x

أي، أي حرف كلمة في نطاق ASCII، طالما أن الحرف الأول ليس رقمًا.

هناك فاصلان للحزم في بيرل: نقطتان مزدوجتان ("::") وعلامة اقتباس فردية ("'"). استخدام "'" كفاصل للحزم مهجور وسيزال في الإصدار 5.40 من بيرل. يمكن للمعرفات العادية أن تبدأ أو تنتهي بنقطتين مزدوجتين، ويمكن أن تحتوي على عدة أجزاء مفصولة بنقطتين مزدوجتين. علامات الاقتباس الفردية لها قواعد مماثلة، ولكن باستثناء أنها ليست قانونية في نهاية المعرف: أي أن "$'foo" و "$foo'bar" قانونيان، ولكن "$foo'bar'" ليس كذلك.

بالإضافة إلى ذلك، إذا سُبق المعرف بـ sigil (الرمز الخاص) -- أي إذا كان المعرف جزءًا من اسم متغير -- فقد يُحاط اختياريًا بأقواس مجعدة.

بينما يمكنك خلط النقطتين المزدوجتين مع علامات الاقتباس الفردية، يجب أن تأتي علامات الاقتباس بعد النقطتين: "$::::'foo" و "$foo::'bar" قانونيان، لكن "$::'::foo" و "$foo'::bar" ليسا كذلك.

بتجميعها معًا، يصبح القواعد النحوية لمطابقة معرف أساسي هي

 /
  (?(DEFINE)
      (?<variable>
          (?&sigil)
          (?:
                  (?&normal_identifier)
              |   \{ \s* (?&normal_identifier) \s* \}
          )
      )
      (?<normal_identifier>
          (?: :: )* '?
           (?&basic_identifier)
           (?: (?= (?: :: )+ '? | (?: :: )* ' ) (?&normal_identifier) )?
          (?: :: )*
      )
      (?<basic_identifier>
        # is use utf8 on?
          (?(?{ (caller(0))[8] & $utf8::hint_bits })
              (?&Perl_XIDS) (?&Perl_XIDC)*
            | (?aa) (?!\d) \w+
          )
      )
      (?<sigil> [&*\$\@\%])
      (?<Perl_XIDS> (?[ ( \p{Word} & \p{XID_Start} ) + [_] ]) )
      (?<Perl_XIDC> (?[ \p{Word} & \p{XID_Continue} ]) )
  )
 /x

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

1.
رمز (sigil)، متبوع حصراً بأرقام تطابق "\p{POSIX_Digit}"، مثل $0، أو $1، أو $10000.
2.
رمز متبوع بحرف واحد يطابق خاصية "\p{POSIX_Punct}"، مثل $! أو "%+"، باستثناء الحرف "{" الذي لا يعمل.
3.
رمز، متبوع بعلامة أقحوان (caret) وأي حرف من الأحرف "[][A-Z^_?\]"، مثل $^V أو $^].
4.
على غرار ما سبق، رمز متبوع بنص bareword داخل أقواس مجعدة، حيث يكون الحرف الأول علامة أقحوان. الحرف التالي هو أي واحد من الأحرف "[][A-Z^_?\]"، متبوعًا بأحرف كلمات ASCII. مثال على ذلك هو "${^GLOBAL_PHASE}".
5.
رمز متبوع بأي حرف واحد في النطاق "[\xA1-\xAC\xAE-\xFF]" عندما لا يكون تحت "use utf8". (تحت "use utf8"، تنطبق قواعد المعرفات العادية المذكورة سابقًا في هذا القسم). مُنع استخدام الأحرف غير الرسومية (عناصر تحكم C1، والمسافة غير المنقسمة، والواصلة الناعمة) منذ الإصدار v5.26.0. استخدام الأحرف الأخرى غير حكيم، حيث إنها جميعًا محجوزة ليكون لها معنى خاص لبيرل، ولا يوجد لأي منها حاليًا معنى خاص، رغم أن هذا قد يتغير دون إشعار.

لاحظ أن أحد الآثار المترتبة على هذا الشكل هو وجود معرفات قانونية فقط تحت "use utf8"، والعكس صحيح، على سبيل المثال المعرف "$état" قانوني تحت "use utf8"، ولكنه بخلاف ذلك يُعتبر المتغير ذو الحرف الواحد متبوعًا بـ "tat"، وهو ما يشكل خطأ في القواعد النحوية.

6.
هذا مزيج من الشكلين السابقين. يكون صالحًا فقط عندما لا يكون تحت "use utf8" (تنطبق قواعد المعرفات العادية عندما تكون تحت "use utf8"). الشكل هو رمز متبوع بنص داخل أقواس مجعدة، حيث يكون الحرف الأول أيًا من الأحرف في النطاق "[\x80-\xFF]" متبوعًا بأحرف كلمات ASCII حتى قوس الإغلاق.

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

قبل الإصدار v5.24 من بيرل، كانت أحرف تحكم ASCII غير الرسومية مسموحة أيضًا في بعض الحالات؛ وقد تم هجر هذا منذ الإصدار v5.20.

السياق

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

بشكل متبادل، توفر العملية إما سياق سكالار أو سياق قائمة لكل من وسائطها. على سبيل المثال، إذا قلت

    int( <STDIN> )

فإن عملية العدد الصحيح توفر سياق سكالار لعامل التشغيل <>، الذي يستجيب بقراءة سطر واحد من STDIN وتمريره مرة أخرى إلى عملية العدد الصحيح، والتي ستجد بعد ذلك القيمة الصحيحة لذلك السطر وتعيدها. أما إذا قلت

    sort( <STDIN> )

فإن عملية الفرز (sort) توفر سياق قائمة لـ <>، والذي سيستمر في قراءة كل سطر متاح حتى نهاية الملف، ويمرر تلك القائمة من السطور مرة أخرى إلى روتين الفرز، الذي سيقوم بعد ذلك بفرز تلك السطور وإعادتها كقائمة إلى أيًا كان سياق الفرز.

التعيين (Assignment) خاص قليلاً لأنه يستخدم وسيطه الأيسر لتحديد سياق الوسيط الأيمن. التعيين لسكالار يقيم الجانب الأيمن في سياق سكالار، بينما التعيين لمصفوفة أو hash يقيم الجانب الأيمن في سياق قائمة. التعيين لقائمة (أو شريحة، وهي مجرد قائمة على أي حال) يقيم أيضًا الجانب الأيمن في سياق قائمة.

عند استخدام توجيه "use warnings" أو خيار سطر الأوامر -w لبيرل، قد ترى تحذيرات حول استخدامات عديمة الفائدة للثوابت أو الدوال في "سياق فارغ" (void context). السياق الفارغ يعني ببساطة أن القيمة قد تم التخلص منها، مثل جملة تحتوي فقط على ""fred";" أو "getpwuid(0);". ولا يزال يُحسب كسياق سكالار للدوال التي تهتم بما إذا كان يتم استدعاؤها في سياق قائمة أم لا.

قد تختار الروتينات الفرعية التي يحددها المستخدم الاهتمام بما إذا كان يتم استدعاؤها في سياق فارغ، أو سكالار، أو قائمة. ومع ذلك، لا تحتاج معظم الروتينات الفرعية إلى الاهتمام بذلك. وذلك لأن كلاً من السكالار والقوائم يتم إقحامها آليًا في القوائم. راجع "wantarray" في perlfunc لمعرفة كيف يمكنك تمييز سياق استدعاء دالتك ديناميكيًا.

قيم السكالار

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

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

تُفسر قيمة السكالار على أنها خطأ (FALSE) بالمعنى البولياني إذا كانت غير معرفة، أو كانت السلسلة الفارغة، أو الرقم 0 (أو ما يعادلها نصيًا "0")، وتكون صواب (TRUE) إذا كانت أي شيء آخر. السياق البولياني هو مجرد نوع خاص من سياق السكالار حيث لا يتم إجراء أي تحويل إلى نص أو رقم. نفي القيمة الصحيحة بواسطة "!" أو "not" يعيد قيمة خطأ خاصة. عند تقييمها كسلسلة نصية تُعامل كـ ""، ولكن كرقم، تُعامل كـ 0. معظم معاملات بيرل التي تعيد صواب أو خطأ تتصرف بهذه الطريقة.

هناك في الواقع نوعان من السلاسل النصية الخالية (يُشار إليها أحيانًا باسم السلاسل "الفارغة")، واحدة معرفة وأخرى غير معرفة. النسخة المعرفة هي مجرد سلسلة بطول صفر، مثل "". النسخة غير المعرفة هي القيمة التي تشير إلى عدم وجود قيمة حقيقية لشيء ما، كما هو الحال عند حدوث خطأ، أو في نهاية ملف، أو عند الإشارة إلى متغير غير مهيأ أو عنصر في مصفوفة أو hash. رغم أنه في إصدارات بيرل المبكرة، كان بإمكان السكالار غير المعرف أن يصبح معرفًا عند استخدامه لأول مرة في مكان يتوقع قيمة معرفة، إلا أن هذا لم يعد يحدث باستثناء حالات نادرة من autovivification كما هو موضح في perlref. يمكنك استخدام معامل defined() لتحديد ما إذا كانت قيمة السكالار معرفة (ليس لهذا معنى في المصفوفات أو الـ hashes)، ومعامل undef() لإنتاج قيمة غير معرفة.

لمعرفة ما إذا كانت سلسلة نصية معينة رقمًا صالحًا غير صفري، يكفي أحيانًا اختبارها مقابل كل من الرقم 0 والكلمة المعجمية "0" (رغم أن هذا سيسبب ضجيجًا إذا كانت التحذيرات مفعلة). وذلك لأن السلاسل التي ليست أرقامًا تُحسب كـ 0، تمامًا كما هو الحال في awk:

    if ($str == 0 && $str ne "0")  {
        warn "هذا لا يبدو وكأنه رقم";
    }

قد تكون هذه الطريقة هي الأفضل لأنه بخلاف ذلك لن تعامل تدوينات IEEE مثل "NaN" أو "Infinity" بشكل صحيح. في أوقات أخرى، قد تفضل تحديد ما إذا كان يمكن استخدام بيانات السلسلة رقميًا من خلال استدعاء دالة POSIX::strtod() أو بفحص السلسلة باستخدام تعبير نمطي (كما هو موثق في perlre).

    warn "يحتوي على غير أرقام"        if     /\D/;
    warn "ليس رقما طبيعيا" unless /^\d+$/;             # يرفض -3
    warn "ليس عددا صحيحا"       unless /^-?\d+$/;           # يرفض +3
    warn "ليس عددا صحيحا"       unless /^[+-]?\d+$/;
    warn "ليس رقما عشريا" unless /^-?\d+\.?\d*$/;     # يرفض .2
    warn "ليس رقما عشريا" unless /^-?(?:\d+(?:\.\d*)?|\.\d+)$/;
    warn "ليس عددا عائما بلغة C"
        unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;

طول المصفوفة هو قيمة سكالار. يمكنك العثور على طول المصفوفة @days بتقييم $#days، كما هو الحال في csh. ومع ذلك، هذا ليس طول المصفوفة؛ بل هو فهرس العنصر الأخير، وهي قيمة مختلفة نظرًا لوجود العنصر رقم 0 عادةً. التعيين لـ $#days يغير بالفعل طول المصفوفة. تقصير المصفوفة بهذه الطريقة يدمر القيم المتداخلة. تطويل مصفوفة تم تقصيرها سابقًا لا يستعيد القيم التي كانت في تلك العناصر.

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

    @whatever = ();
    $#whatever = -1;

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

    scalar(@whatever) == $#whatever + 1;

يختار بعض المبرمجين استخدام تحويل صريح حتى لا يتركوا مجالاً للشك:

    $element_count = scalar(@whatever);

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

قبل الإصدار 5.25 من بيرل، كانت القيمة المعادة عبارة عن سلسلة نصية تتكون من عدد الحاويات (buckets) المستخدمة وعدد الحاويات المخصصة، مفصولة بشرطة مائلة. هذا مفيد فقط لمعرفة ما إذا كانت خوارزمية الـ hashing الداخلية لبيرل تعمل بشكل سيئ على مجموعة بياناتك. على سبيل المثال، تضع 10,000 عنصر في hash، لكن تقييم %HASH في سياق سكالار يكشف عن "1/16"، مما يعني أنه تم لمس واحدة فقط من أصل ست عشرة حاوية، ويُفترض أنها تحتوي على جميع العناصر الـ 10,000. ليس من المفترض أن يحدث هذا.

بدءًا من الإصدار 5.25 من بيرل، غُيرت القيمة المعادة لتكون عدد المفاتيح في الـ hash. إذا كنت بحاجة للوصول إلى السلوك القديم، يمكنك استخدام Hash::Util::bucket_ratio() بدلاً من ذلك.

إذا قُيمت دالة هاش مربوطة (tied hash) في سياق عددي (scalar context)، تُستدعى الوسيلة "SCALAR" (مع الرجوع إلى "FIRSTKEY" في حال الإخفاق).

يمكنك حجز مساحة مسبقًا لدالة هاش عبر التعيين للدالة keys(). يؤدي هذا إلى تقريب الدلاء (buckets) المخصصة إلى القوة التالية للعدد اثنين:

    keys(%users) = 1000;                # حجز 1024 دلوًا

منشئات القيمة العددية

تُحدد الأرقام الحرفية بأي من تنسيقات الفاصلة العائمة أو الأعداد الصحيحة التالية:

 12345
 12345.67
 .23E-10             # رقم صغير جدًا
 3.14_15_92          # رقم مهم جدًا
 4_294_967_296       # شرطة سفلية للوضوح
 0xff                # سداسي عشر
 0xdead_beef         # المزيد من السداسي عشر
 0377                # ثماني (أرقام فقط، يبدأ بـ 0)
 0o12_345            # ثماني بديل (أُدخل في Perl 5.33.5)
 0b011011            # ثنائي
 0x1.999ap-4         # فاصلة عائمة سداسية عشرية (حرف 'p' مطلوب)

يُسمح لك باستخدام الشرطات السفلية في الأرقام الحرفية بين الأرقام لسهولة القراءة (ولكن ليس شرطات سفلية متعددة متتالية: "23__500" غير قانوني؛ بينما "23_500" قانوني). يمكنك، على سبيل المثال، تجميع الأرقام الثنائية في مجموعات من ثلاثة (كما في معامل الوضع بأسلوب يونكس مثل 0b110_100_100) أو أربعة (لتمثيل النيبلات nibbles، كما في 0b1010_0110) أو في مجموعات أخرى.

تُحدد السلاسل الحرفية عادةً إما بعلامات اقتباس مفردة أو مزدوجة. وهي تعمل بشكل مشابه جدًا لعلامات الاقتباس في صدفات يونكس القياسية: تخضع السلاسل الحرفية ذات الاقتباس المزدوج لتبديل المتغيرات والشرطة المائلة العكسية؛ بينما لا تخضع السلاسل ذات الاقتباس المفرد لذلك (باستثناء "\'" و "\\"). تنطبق قواعد الشرطة المائلة العكسية المعتادة بأسلوب C لإنشاء محارف مثل السطر الجديد، والتبويب، وما إلى ذلك، بالإضافة إلى بعض الأشكال الأكثر غرابة. انظر "Quote and Quote-like Operators" في perlop للحصول على قائمة.

لا تُحول التمثيلات السداسية العشرية، أو الثمانية، أو الثنائية في السلاسل الحرفية (مثل '0xff') آليًا إلى تمثيلها العددي الصحيح. تقوم الدالتان hex() و oct() بهذه التحويلات لك. انظر "hex" في perlfunc و "oct" في perlfunc لمزيد من التفاصيل.

يمكن أن تبدأ الفاصلة العائمة السداسية العشرية تمامًا مثل الحرفي السداسي العشر، ويمكن أن يتبعها جزء سداسي عشري كسرى اختياري، ولكن يجب أن يتبعها "p"، وإشارة اختيارية، وقوة للعدد اثنين. هذا التنسيق مفيد لتمثيل قيم الفاصلة العائمة بدقة، وتجنب التحويلات من أو إلى الفاصلة العائمة العشرية، وبالتالي تجنب الفقد المحتمل في الدقة. لاحظ أنه بينما تستخدم معظم المنصات الحالية فاصلة عائمة IEEE 754 بـ 64 بت، لا تفعل جميعها ذلك. مصدر محتمل آخر للاختلافات (في المراتب الدنيا) هو أوضاع تقريب الفاصلة العائمة، والتي يمكن أن تختلف بين المعالجات، وأنظمة التشغيل، والمترجمات، والتي لا تتحكم فيها Perl.

يمكنك أيضًا تضمين أسطر جديدة مباشرة في سلاسلك النصية، أي يمكن أن تنتهي في سطر مختلف عن الذي بدأت فيه. هذا أمر جيد، ولكن إذا نسيت علامة الاقتباس الختامية، فلن يُبلغ عن الخطأ حتى تجد Perl سطرًا آخر يحتوي على محرف الاقتباس، والذي قد يكون بعيدًا جدًا في السكربت. يقتصر تبديل المتغيرات داخل السلاسل النصية على المتغيرات العددية، والمصفوفات، وشرائح المصفوفات أو الهاش. (بمعنى آخر، الأسماء التي تبدأ بـ $ أو @، متبوعة بتعبير اختياري بين أقواس كمؤشر سفلي subscript.) مقطع الكود التالي يطبع "The price is $100."

    $Price = '$100';    # لا يستوفى
    print "The price is $Price.\n";     # يستوفى

لا يوجد استيفاء مزدوج في Perl، لذا تترك $100 كما هي.

مبدئيًا، تستخدم أرقام الفاصلة العائمة المستبدلة داخل السلاسل النصية النقطة (".") كفاصل عشري. إذا كان "use locale" قيد التنفيذ، واستُدعيت POSIX::setlocale()، فإن المحرف المستخدم للفاصل العشري يتأثر بإعدادات LC_NUMERIC المحلية. انظر perllocale و POSIX.

أسماء المتغيرات المحددة باستخدام الأقواس المعقوفة

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

    $who = "Larry";
    print PASSWD "${who}::0:0:Superuser:/:/bin/perl\n";
    print "We use ${who}speak when ${who}'s here.\n";

بدون الأقواس المعقوفة، كانت Perl ستبحث عن المتغيرات $whospeak، و $who::0، و "$who's". المتغيران الأخيران سيكونا $0 و $s في حزمة (يُفترض) أنها غير موجودة تسمى "who".

في الواقع، يُجبر المعرف البسيط داخل هذه الأقواس المعقوفة على أن يكون سلسلة نصية، وبالمثل داخل مؤشر الهاش السفلي. لا يحتاج أي منهما إلى اقتباس. مثالنا السابق، $days{'Feb'} يمكن كتابته كـ $days{Feb} وستُفترض علامات الاقتباس آليًا. ولكن أي شيء أكثر تعقيدًا في المؤشر السفلي سيُفسر كتعبير. وهذا يعني على سبيل المثال أن "$version{2.0}++" تكافئ "$version{2}++"، وليس "$version{'2.0'}++".

توجد مشكلة مماثلة في الاستيفاء مع النص الذي يشبه تدوين الوصول إلى المصفوفة أو الهاش. وضع متغير بسيط مثل $who مباشرة أمام نص مثل "[1]" أو "{foo}" سيؤدي إلى استيفاء المتغير كوصول إلى عنصر في @who أو قيمة مخزنة في %who:

    $who = "Larry Wall";
    print "$who[1] is the father of Perl.\n";

سيحاول الوصول إلى الفهرس 1 لمصفوفة تسمى @who. مرة أخرى، استخدام الأقواس سيمنع حدوث ذلك:

    $who = "Larry Wall";
    print "${who}[1] is the father of Perl.\n";

سيُعامل بنفس طريقة

    $who = "Larry Wall";
    print $who . "[1] is the father of Perl.\n";

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

    @name = qw(Larry Curly Moe);
    print "Also ${name[0]}[1] was a member\n";

بدون الأقواس، سيُحلل المثال أعلاه كمؤشر مصفوفة من مستويين في مصفوفة @name، وتحت "use strict" سينتج على الأرجح استثناءً قاتلاً، لأنه سيُحلل هكذا:

    print "Also " . $name[0][1] . " was a member\n";

وليس كما هو مقصود:

    print "Also " . $name[0] . "[1] was a member\n";

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

    @name = qw(Larry Curly Moe);
    print "Also $name[0]\[1] was a member\n";

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

تأمل المصفوفة السحرية "@{^CAPTURE}" التي يملؤها محرك التعبيرات النمطية بمحتويات جميع مخازن الالتقاط في نمط ما (انظر perlvar و perlre). الطريقة الوحيدة التي يمكنك بها الوصول إلى أحد هذه الأعضاء داخل سلسلة نصية هي عبر الشكل المحاط بأقواس (المحدد):

    "abc"=~/(.)(.)(.)/
        and print "Second buffer is ${^CAPTURE[1]}";

يكافئ

    "abc"=~/(.)(.)(.)/
        and print "Second buffer is " . ${^CAPTURE}[1];

قول "@^CAPTURE" هو خطأ في بناء الجملة، لذا يجب الإشارة إليه كـ "@{^CAPTURE}"، وللوصول إلى أحد عناصره في الكود العادي ستكتب " ${^CAPTURE}[1] ". ومع ذلك عند الاستيفاء في سلسلة نصية "${^CAPTURE}[1]" سيكون مكافئًا لـ "${^CAPTURE} . "[1]""، والذي لا يشير حتى إلى نفس المتغير! وبالتالي يجب أيضًا وضع المؤشرات السفلية داخل الأقواس: "${^CAPTURE[1]}".

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

    @name = qw(Larry Curly Moe);
    local $" = " and ";
    print "My favorites were @{name[1,2]}.\n";

سيخرج

    My favorites were Curly and Moe.

فاصلة عائمة خاصة: اللانهاية (Inf) وليس رقمًا (NaN)

تتضمن قيم الفاصلة العائمة القيم الخاصة "Inf" و "NaN"، للانهاية وليس رقمًا. يمكن أن تكون اللانهاية سالبة أيضًا.

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

للانهاية و "ليس رقمًا" قواعد حسابية خاصة بهما. القاعدة العامة هي أنهما "معديان": "Inf" زائد واحد هو "Inf"، و "NaN" زائد واحد هو "NaN". تزداد الأمور إثارة عندما تجمع بين اللانهايات وقيم "ليس رقمًا": "Inf" ناقص "Inf" و "Inf" مقسومًا على "Inf" هي "NaN" (بينما "Inf" زائد "Inf" هو "Inf" و "Inf" ضرب "Inf" هو "Inf"). وقيمة "NaN" غريبة أيضًا في أنها لا تساوي أي رقم، بما في ذلك نفسها: "NaN" != "NaN".

لا تفهم Perl قيم "Inf" و "NaN" كأرقام حرفية، ولكن يمكنك الحصول عليها كسلاسل نصية، وستقوم Perl بتحويلها حسب الحاجة: "Inf" + 1. (ومع ذلك، يمكنك استيرادها من ملحق POSIX؛ "use POSIX qw(Inf NaN);" ثم استخدامها كأرقام حرفية.)

لاحظ أنه عند الإدخال (من سلسلة نصية إلى رقم) تقبل Perl "Inf" و "NaN" بأشكال عديدة. يتم تجاهل حالة الأحرف، وتُفهم الأشكال الخاصة بـ Win32 مثل "1.#INF"، ولكن عند الإخراج يتم تطبيع القيم إلى "Inf" و "NaN".

سلاسل الإصدار

يُحلل الحرفي الذي يأتي على الشكل "v1.20.300.4000" كسلسلة نصية مكونة من محارف ذات أرقام ترتيبية محددة. يوفر هذا الشكل، المعروف باسم v-strings، طريقة بديلة وأكثر قابلية للقراءة لإنشاء السلاسل، بدلاً من استخدام شكل الاستيفاء الأقل قابلية للقراءة "\x{1}\x{14}\x{12c}\x{fa0}". هذا مفيد لتمثيل سلاسل يونيكود، ومقارنة "أرقام" الإصدارات باستخدام معاملات مقارنة السلاسل، "cmp"، و "gt"، و "lt" وما إلى ذلك. إذا كان هناك نقطتان أو أكثر في الحرفي، فيمكن حذف حرف "v" البادئ.

    print v9786;              # يطبع SMILEY، "\x{263a}"
    print v102.111.111;       # يطبع "foo"
    print 102.111.111;        # نفس الشيء

تُقبل هذه الأحرف الحرفية من قِبل كل من "require" و "use" لإجراء فحص الإصدار. لاحظ أن استخدام v-strings لعناوين IPv4 ليس قابلاً للنقل ما لم تستخدم أيضًا روتينات inet_aton()/inet_ntoa() الخاصة بحزمة Socket.

لاحظ أنه منذ الإصدار Perl 5.8.1، لا تُعد v-strings ذات الرقم الواحد (مثل "v65") سلاسل v-strings قبل معامل "=>" (الذي يُستخدم عادةً لفصل مفتاح الهاش عن قيمته)؛ وبدلاً من ذلك تُفسر كسلاسل حرفية ('v65'). كانت تُعتبر v-strings من الإصدار Perl 5.6.0 إلى 5.8.0، ولكن ذلك تسبب في ارتباك وأعطال أكثر من النفع. أما v-strings متعددة الأرقام مثل "v65.66" و 65.66.67 فتستمر في كونها v-strings دائمًا.

أحرف حرفية خاصة

تمثل الأحرف الحرفية الخاصة __FILE__ و __LINE__ و __PACKAGE__ اسم الملف الحالي، ورقم السطر، واسم الحزمة في تلك النقطة من برنامجك. ويعطي __SUB__ مرجعًا للروتين الفرعي الحالي. لا يجوز استخدامها إلا كرموز (tokens) منفصلة؛ ولن تُستوفى داخل السلاسل النصية. إذا لم تكن هناك حزمة حالية (بسبب توجيه "package;" فارغ)، فإن __PACKAGE__ سيكون القيمة غير المحددة. (لكن "package;" الفارغ لم يعد مدعومًا اعتبارًا من الإصدار 5.10.) خارج الروتين الفرعي، يكون __SUB__ هو القيمة غير المحددة. لا يتوفر __SUB__ إلا في الإصدار 5.16 أو أعلى، وفقط مع إعلان "use v5.16" أو "use feature "current_sub"".

يمكن استخدام محرفي التحكم ^D و ^Z، والرمزين __END__ و __DATA__ للإشارة إلى النهاية المنطقية للسكربت قبل نهاية الملف الفعلية. يتم تجاهل أي نص تالٍ من قِبل المفسر ما لم يقرأه البرنامج كما هو موضح أدناه.

يمكن قراءة النص بعد __DATA__ عبر مقبض الملف "PACKNAME::DATA"، حيث "PACKNAME" هي الحزمة التي كانت نشطة عند العثور على الرمز __DATA__. يُترك مقبض الملف مفتوحًا ليشير إلى السطر الذي يلي __DATA__. يجب على البرنامج "close DATA" عند الانتهاء من القراءة منه. (تركه مفتوحًا يسرب مقابض الملفات إذا أُعيد تحميل الوحدة لأي سبب، لذا فمن الممارسات الأكثر أمانًا إغلاقه.) للتوافق مع السكربتات القديمة المكتوبة قبل إدخال __DATA__، يتصرف __END__ مثل __DATA__ في السكربت ذي المستوى الأعلى (ولكن ليس في الملفات المحملة عبر "require" أو "do") ويترك بقية محتويات الملف قابلة للوصول عبر "main::DATA".

  while (my $line = <DATA>) { print $line; }
  close DATA;
  __DATA__
  Hello world.

يمتلك مقبض الملف "DATA" مبدئيًا أي طبقات PerlIO كانت موجودة عندما قرأت Perl الملف لتحليل المصدر. يعني هذا عادةً أن الملف يُقرأ بالبايت، كما لو كان مرموزًا بـ Latin-1، ولكن هناك طريقتان رئيستان ليكون الأمر خلاف ذلك. أولاً، إذا كان الرمز "__END__"/"__DATA__" في نطاق براغما "use utf8" فإن مقبض "DATA" سيكون في وضع UTF-8. وثانيًا، إذا كان المصدر يُقرأ من دخل perl القياسي، فإن مقبض الملف "DATA" يُلقب فعليًا باسم مقبض الملف "STDIN"، وقد يكون في وضع UTF-8 بسبب متغير البيئة "PERL_UNICODE" أو مفاتيح سطر الأوامر الخاصة بـ perl.

انظر SelfLoader لمزيد من الوصف لـ __DATA__، ومثال على استخدامه. لاحظ أنه لا يمكنك القراءة من مقبض ملف DATA في كتلة BEGIN: تُنفذ كتلة BEGIN بمجرد رؤيتها (أثناء الترجمة)، وفي تلك النقطة يكون الرمز المقابل __DATA__ (أو __END__) لم يُرَ بعد.

Barewords (الكلمات المجردة)

تُعامل الكلمة التي ليس لها تفسير آخر في قواعد اللغة كما لو كانت سلسلة نصية مقتبسة. تُعرف هذه باسم "barewords". كما هو الحال مع مقابض الملفات واللصائق، فإن الكلمة المجردة التي تتكون بالكامل من أحرف صغيرة تخاطر بالتعارض مع كلمات محجوزة مستقبلاً، وإذا كنت تستخدم براغما "use warnings" أو مفتاح -w، فستحذرك Perl من أي كلمات من هذا القبيل. تحد Perl الكلمات المجردة (مثل المعرفات) بحوالي 250 محرفًا. ومن المرجح أن تلغي الإصدارات المستقبلية من Perl هذه القيود التعسفية.

قد يرغب البعض في منع الكلمات المجردة تمامًا. إذا قلت

    use strict 'subs';

فإن أي كلمة مجردة لن تُفسر كاستدعاء روتين فرعي ستنتج خطأ في وقت الترجمة بدلاً من ذلك. يستمر هذا القيد حتى نهاية الكتلة المحيطة. ويمكن لكتلة داخلية إلغاء هذا بقول "no strict 'subs'".

استيفاء المصفوفة

تُستوفى المصفوفات والشرائح داخل السلاسل النصية ذات الاقتباس المزدوج عبر ربط العناصر بالفاصل المحدد في المتغير $" (أو $LIST_SEPARATOR إذا حُدد "use English;")، وهو المسافة مبدئيًا. ما يلي متكافئ:

    $temp = join($", @ARGV);
    system "echo $temp";
    system "echo @ARGV";

داخل أنماط البحث (التي تخضع أيضًا لتبديل الاقتباس المزدوج) هناك لبس مؤسف: هل يُفسر "/$foo[bar]/" على أنه "/${foo}[bar]/" (حيث "[bar]" هي فئة محارف للتعبير النمطي) أم على أنه "/${foo[bar]}/" (حيث "[bar]" هو المؤشر السفلي للمصفوفة @foo)؟ إذا كانت @foo غير موجودة أصلاً، فمن الواضح أنها فئة محارف. وإذا كانت @foo موجودة، فإن Perl تخمن بشأن "[bar]"، وغالبًا ما تكون محقة. وإذا خمنت بشكل خاطئ، أو إذا كنت تشعر بالقلق، يمكنك فرض التفسير الصحيح باستخدام الأقواس المعقوفة كما سبق.

إذا كنت تبحث عن معلومات حول كيفية استخدام مستندات-هنا (here-documents)، والتي كانت موجودة هنا سابقًا، فقد نُقلت إلى "Quote and Quote-like Operators" في perlop.

منشئات قيمة القائمة

يُشار إلى قيم القائمة بفصل القيم الفردية بفاصلات (وإحاطة القائمة بأقواس حيث تتطلب الأسبقية ذلك):

    (قائمة)

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

    @foo = ('cc', '-E', $bar);

يعين قيمة القائمة بأكملها للمصفوفة @foo، ولكن

    $foo = ('cc', '-E', $bar);

يعين قيمة المتغير $bar للمتغير العددي $foo. لاحظ أن قيمة المصفوفة الفعلية في السياق العددي هي طول المصفوفة؛ التالي يعين القيمة 3 لـ $foo:

    @foo = ('cc', '-E', $bar);
    $foo = @foo;                # $foo يحصل على 3

يمكنك وضع فاصلة اختيارية قبل قوس الإغلاق لحرفي القائمة، بحيث يمكنك قول:

    @foo = (
        1,
        2,
        3,
    );

لاستخدام مستند-هنا لتعيين مصفوفة، سطر واحد لكل عنصر، قد تستخدم نهجًا مثل هذا:

    @sauces = <<End_Lines =~ m/(\S.*\S)/g;
        normal tomato
        spicy tomato
        green chile
        pesto
        white wine
    End_Lines

تجري القوائم (LISTs) استكمالاً آلياً للقوائم الفرعية. أي أنه عند تقييم قائمة (LIST)، يُقيّم كل عنصر من عناصرها في سياق القائمة، وتُستكمل قيمة القائمة الناتجة داخل القائمة (LIST) تماماً كما لو كان كل عنصر فردي عضواً في القائمة. وبالتالي تفقد المصفوفات والمفرومات هويتها في القائمة (LIST)--حيث إن القائمة

    (@foo,@bar,&SomeSub,%glarch)

تحتوي على كافة عناصر @foo تليها كافة عناصر @bar، تليها كافة العناصر التي يعيدها الروتين الفرعي المسمى SomeSub والمستدعى في سياق القائمة، تليها أزواج المفتاح/القيمة لـ %glarch. لإنشاء مرجع قائمة لا يُستكمل، انظر perlref.

تُمثّل القائمة الفارغة بالرمز (). ولا يكون لاستكمالها في قائمة أي أثر. وبالتالي فإن ((),(),()) تكافئ (). وبالمثل، فإن استكمال مصفوفة بلا عناصر هو تماماً كعدم استكمال أي مصفوفة في تلك النقطة.

يتحد هذا الاستكمال مع حقيقة أن القوسين الافتتاحي والختامي اختياربان (إلا عند الضرورة لتحديد الأسبقية) وأن القوائم قد تنتهي بفاصلة اختيارية، مما يعني أن الفواصل المتعددة داخل القوائم تعد صياغة قانونية. القائمة "1,,3" هي دمج لقائمتين، "1," و 3، الأولى منهما تنتهي بتلك الفاصلة الاختيارية. "1,,3" هي "(1,),(3)" وهي "1,3" (وبالمثل لـ "1,,,3" التي هي "(1,),(,),3" وهي "1,3" وهكذا دواليك.) لا يعني هذا أننا ننصحك باستخدام هذا التعمية.

يمكن أيضاً فهرسة قيمة القائمة مثل المصفوفة العادية. يجب وضع القائمة بين قوسين لتجنب اللبس. على سبيل المثال:

    # تعيد Stat قيمة قائمة.
    $time = (stat($file))[8];
    # خطأ في الصيغة هنا.
    $time = stat($file)[8];  # عذراً، نسيت الأقواس
    # البحث عن رقم ست عشري.
    $hexdigit = ('a','b','c','d','e','f')[$digit-10];
    # "عامل فاصلة عكسي".
    return (pop(@foo),pop(@foo))[0];

لا يمكن التعيين للقوائم إلا عندما يكون كل عنصر في القائمة قابلاً للتعيين إليه قانونياً:

    ($x, $y, $z) = (1, 2, 3);
    ($map{'red'}, $map{'blue'}, $map{'green'}) = (0x00f, 0x0f0, 0xf00);

الاستثناء الوحيد لهذا هو إمكانية التعيين لـ "undef" في قائمة. وهذا مفيد للتخلص من بعض القيم التي يعيدها التابع:

    ($dev, $ino, undef, undef, $uid, $gid) = stat($file);

بدءاً من Perl 5.22، يمكنك أيضاً استخدام "(undef)x2" بدلاً من "undef, undef". (يمكنك أيضاً إجراء "($x) x 2"، وهو أقل فائدة لأنه يعين لنفس المتغير مرتين، مما يؤدي لمحو القيمة الأولى المعينة.)

عند تعيين قائمة من القيم السلمية إلى مصفوفة، تُمسح كافة القيم السابقة في تلك المصفوفة ويصبح عدد عناصر المصفوفة الآن مساوياً لعدد العناصر في القائمة التي على الطرف الأيمن -- القائمة التي تم التعيين منها. ستغير المصفوفة حجمها آلياً لتتسع بدقة لكل عنصر في القائمة اليمنى.

    use warnings;
    my (@xyz, $x, $y, $z);
    @xyz = (1, 2, 3);
    print "@xyz\n";                             # 1 2 3
    @xyz = ('al', 'be', 'ga', 'de');
    print "@xyz\n";                             # al be ga de
    @xyz = (101, 102);
    print "@xyz\n";                             # 101 102

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

    ($x, $y, $z) = (1, 2, 3);
    print "$x $y $z\n";                         # 1 2 3
    ($x, $y, $z) = ('al', 'be', 'ga', 'de');
    print "$x $y $z\n";                         # al be ga
    ($x, $y, $z) = (101, 102);
    print "$x $y $z\n";                         # 101 102
    # استخدام قيمة غير مهيأة $z في السلسلة (.)
    # أو السلسلة النصية في [البرنامج] السطر [رقم السطر].

إذا كان عدد القيم السلمية في القائمة اليسرى أقل من القائمة اليمنى، فلن تُعين القيم السلمية "الزائدة" في القائمة اليمنى ببساطة.

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

    ($x, $y, $z) = (101, 102);
    for my $el ($x, $y, $z) {
        (defined $el) ? print "$el " : print "<undef>";
    }
    print "\n";
                                                # 101 102 <undef>

يعيد تعيين القائمة في سياق سلمي عدد العناصر التي أنتجها التعبير على الطرف الأيمن من التعيين:

    $x = (($foo,$bar) = (3,2,1));       # تُضبط $x لتكون 3، وليس 2
    $x = (($foo,$bar) = f());           # تُضبط $x لتكون عدد القيم التي أعادها f()

يكون هذا مفيداً عندما تريد إجراء تعيين قائمة في سياق منطقي، لأن معظم دوال القوائم تعيد قائمة فارغة عند الانتهاء، مما ينتج 0 عند التعيين، وهو ما يُفسر على أنه خطأ (FALSE).

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

    $count = () = $string =~ /\d+/g;

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

    $count = $string =~ /\d+/g;

ما كان ليعمل، لأن مطابقة النمط في السياق السلمي لن تعيد سوى صح أو خطأ، بدلاً من عدد المطابقات.

قد يكون العنصر الأخير في تعيين القائمة مصفوفة أو مفرومة:

    ($x, $y, @rest) = split;
    my($x, $y, %rest) = @_;

يمكنك في الواقع وضع مصفوفة أو مفرومة في أي مكان في القائمة، ولكن الأولى في القائمة ستمتص جميع القيم، وأي شيء بعدها سيصبح غير معرف (undefined). قد يكون هذا مفيداً في my() أو local().

يمكن تهيئة المفرومة باستخدام قائمة حرفية تحتوي على أزواج من العناصر التي ستُفسر كمفتاح وقيمة:

    # نفس تعيين الخارطة أعلاه
    %map = ('red',0x00f,'blue',0x0f0,'green',0xf00);

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

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

    %map = (
                 red   => 0x00f,
                 blue  => 0x0f0,
                 green => 0xf00,
   );

أو لتهيئة مراجع مفرومات لتستخدم كسجلات:

    $rec = {
                witch => 'Mable the Merciless',
                cat   => 'Fluffy the Ferocious',
                date  => '10/31/1776',
    };

أو لاستخدام الاستدعاء بالمعاملات المسماة للدوال المعقدة:

   $field = $query->radio_group(
               name      => 'group_name',
               values    => ['eenie','meenie','minie'],
               default   => 'meenie',
               linebreak => 'true',
               labels    => \%labels
   );

لاحظ أنه مجرد تهيئة مفرومة بهذا الترتيب لا يعني أنها ستخرج بنفس الترتيب. انظر "sort" في perlfunc لمعرفة أمثلة عن كيفية ترتيب المخرجات.

إذا ظهر مفتاح أكثر من مرة في قائمة تهيئة مفرومة، فإن الظهور الأخير هو الذي يسود:

    %circle = (
                  center => [5, 10],
                  center => [27, 9],
                  radius => 100,
                  color => [0xDF, 0xFF, 0x00],
                  radius => 54,
    );
    # نفس
    %circle = (
                  center => [27, 9],
                  color => [0xDF, 0xFF, 0x00],
                  radius => 54,
    );

يمكن استخدام هذا لتوفير إعدادات مبدئية للتكوين قابلة للتجاوز:

    # القيم في %args لها الأولوية على %config_defaults
    %config = (%config_defaults, %args);

الفهارس (Subscripts)

يمكن الوصول إلى المصفوفة عنصراً سلمياً واحداً في كل مرة بتحديد علامة الدولار ("$")، ثم اسم المصفوفة (بدون علامة "@" البادئة)، ثم الفهرس داخل أقواس مربعة. على سبيل المثال:

    @myarray = (5, 50, 500, 5000);
    print "العنصر الثالث هو ", $myarray[2], "\n";

تبدأ فهارس المصفوفة بـ 0. الفهرس السالب يستعيد قيمته من النهاية. في مثالنا، ستكون قيمة $myarray[-1] هي 5000، وقيمة $myarray[-2] هي 500.

فهارس المفرومات مشابهة، ولكن تستخدم الأقواس المجعدة بدلاً من الأقواس المربعة. على سبيل المثال:

    %scientists =
    (
        "Newton" => "Isaac",
        "Einstein" => "Albert",
        "Darwin" => "Charles",
        "Feynman" => "Richard",
    );
    print "الاسم الأول لداروين هو ", $scientists{"Darwin"}, "\n";

يمكنك أيضاً فهرسة قائمة للحصول على عنصر واحد منها:

    $dir = (getpwnam("daemon"))[7];

محاكاة المصفوفة متعددة الأبعاد

يمكن محاكاة المصفوفات متعددة الأبعاد بفهرسة مفرومة بواسطة قائمة. تُدمج عناصر القائمة باستخدام فاصل الفهارس (انظر "$;" في perlvar).

    $foo{$x,$y,$z}

يكافئ

    $foo{join($;, $x, $y, $z)}

فاصل الفهارس المبدئي هو "\034"، وهو نفس SUBSEP في awk.

الشرائح (Slices)

تصل الشريحة إلى عدة عناصر من قائمة، أو مصفوفة، أو مفرومة في آن واحد باستخدام قائمة من الفهارس. وهي أكثر ملاءمة من كتابة العناصر الفردية كقائمة من القيم السلمية المنفصلة.

    ($him, $her)   = @folks[0,-1];              # شريحة مصفوفة
    @them          = @folks[0 .. 3];            # شريحة مصفوفة
    ($who, $home)  = @ENV{"USER", "HOME"};      # شريحة مفرومة
    ($uid, $dir)   = (getpwnam("daemon"))[2,7]; # شريحة قائمة

بما أنه يمكنك التعيين لقائمة من المتغيرات، يمكنك أيضاً التعيين لشريحة مصفوفة أو مفرومة.

    @days[3..5]    = qw/Wed Thu Fri/;
    @colors{'red','blue','green'}
                   = (0xff0000, 0x0000ff, 0x00ff00);
    @folks[0, -1]  = @folks[-1, 0];

التعيينات السابقة تكافئ تماماً

    ($days[3], $days[4], $days[5]) = qw/Wed Thu Fri/;
    ($colors{'red'}, $colors{'blue'}, $colors{'green'})
                   = (0xff0000, 0x0000ff, 0x00ff00);
    ($folks[0], $folks[-1]) = ($folks[-1], $folks[0]);

بما أن تغيير شريحة يغير المصفوفة أو المفرومة الأصلية التي تم تشريحها، فإن بنية "foreach" ستغير بعض -- أو حتى كل -- قيم المصفوفة أو المفرومة.

    foreach (@array[ 4 .. 10 ]) { s/peter/paul/ }
    foreach (@hash{qw[key1 key2]}) {
        s/^\s+//;                       # تقليم المساحات البيضاء البادئة
        s/\s+$//;                       # تقليم المساحات البيضاء اللاحقة
        s/\b(\w)(\w*)\b/\u$1\L$2/g;     # تحويل الكلمات إلى "حالة العنوان"
    }

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

    @a = ()[0,1];          # @a ليس بها عناصر
    @b = (@a)[0,1];        # @b ليس بها عناصر
    @c = (sub{}->())[0,1]; # @c ليس بها عناصر
    @d = ('a','b')[0,1];   # @d بها عنصران
    @e = (@d)[0,1,8,9];    # @e بها أربعة عناصر
    @f = (@d)[8,9];        # @f بها عنصران

هذا يسهل كتابة حلقات تنتهي عندما تُعاد قائمة فارغة:

    while ( ($home, $user) = (getpwent)[7,0] ) {
        printf "%-8s %s\n", $user, $home;
    }

كما ذُكر سابقاً في هذا المستند، المعنى السلمي لتعيين القائمة هو عدد العناصر الموجودة على الطرف الأيمن من التعيين. القائمة الفارغة لا تحتوي على عناصر، لذا عندما ينفد ملف كلمة السر، تكون النتيجة 0، وليس 2.

تعيد الشرائح في السياق السلمي العنصر الأخير من الشريحة.

    @a = qw/first second third/;
    %h = (first => 'A', second => 'B');
    $t = @a[0, 1];                  # قيمة $t الآن هي 'second'
    $u = @h{'first', 'second'};     # قيمة $u الآن هي 'B'

إذا كنت مرتبكاً بشأن سبب استخدام '@' في شريحة المفرومة بدلاً من '%'، ففكر في الأمر على النحو التالي. نوع القوس (مربع أو مجعد) يحدد ما إذا كان ما يُنظر إليه هو مصفوفة أم مفرومة. من ناحية أخرى، فإن الرمز البادئ ('$' أو '@') على المصفوفة أو المفرومة يشير إلى ما إذا كنت ستحصل على قيمة مفردة (سلمية) أو جمع (قائمة).

شرائح مفتاح/قيمة للمفرومة

بدءاً من Perl 5.20، تعد عملية شريحة المفرومة باستخدام الرمز % نوعاً من أنواع عمليات التشريح التي تعيد قائمة من أزواج المفتاح/القيمة بدلاً من القيم فقط:

    %h = (blonk => 2, foo => 3, squink => 5, bar => 8);
    %subset = %h{'foo', 'bar'}; # شريحة مفتاح/قيمة للمفرومة
    # %subset هي الآن (foo => 3, bar => 8)
    %removed = delete %h{'foo', 'bar'};
    # %removed هي الآن (foo => 3, bar => 8)
    # %h هي الآن (blonk => 2, squink => 5)

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

شرائح فهرس/قيمة للمصفوفة

على غرار شرائح مفتاح/قيمة للمفرومة (والتي قُدمت أيضاً في Perl 5.20)، تعيد صيغة شريحة المصفوفة % قائمة من أزواج الفهرس/القيمة:

    @a = "a".."z";
    @list = %a[3,4,6];
    # @list هي الآن (3, "d", 4, "e", 6, "g")
    @removed = delete %a[3,4,6]
    # @removed هي الآن (3, "d", 4, "e", 6, "g")
    # @list[3,4,6] هي الآن undef

لاحظ أن استدعاء "delete" على قيم المصفوفة هو أمر غير محبذ بشدة.

أشكال الأنواع (Typeglobs) ومقابض الملفات

تستخدم Perl نوعاً داخلياً يسمى typeglob لحفظ مدخل كامل في جدول الرموز. بادئة النوع لـ typeglob هي "*"، لأنها تمثل جميع الأنواع. كان هذا هو الأسلوب المفضل لتمرير المصفوفات والمفرومات بالمرجع إلى الدالة، ولكن الآن بما أننا نملك مراجع حقيقية، نادراً ما تبرز الحاجة إلى ذلك.

الاستخدام الرئيسي لـ typeglobs في Perl الحديثة هو إنشاء أسماء مستعارة لجدول الرموز. هذا التعيين:

    *this = *that;

يجعل $this اسماً مستعاراً لـ $that، و @this اسماً مستعاراً لـ @that، و %this اسماً مستعاراً لـ %that، و &this اسماً مستعاراً لـ &that، إلخ. الأكثر أماناً هو استخدام المرجع. هذا:

    local *Here::blue = \$There::green;

يجعل $Here::blue مؤقتاً اسماً مستعاراً لـ $There::green، ولكنه لا يجعل @Here::blue اسماً مستعاراً لـ @There::green، أو %Here::blue اسماً مستعاراً لـ %There::green، إلخ. انظر "Symbol Tables" في perlmod لمزيد من الأمثلة على ذلك. رغم غرابة الأمر، إلا أن هذا هو الأساس لنظام استيراد وتصدير الوحدات بأكمله.

استخدام آخر لـ typeglobs هو تمرير مقابض الملفات إلى دالة أو إنشاء مقابض ملفات جديدة. إذا كنت بحاجة لاستخدام typeglob لحفظ مقبض ملف، فافعل ذلك بهذه الطريقة:

    $fh = *STDOUT;

أو ربما كمرجع حقيقي، هكذا:

    $fh = \*STDOUT;

انظر perlsub لمعرفة أمثلة عن استخدام هذه كمقابض ملفات غير مباشرة في الدوال.

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

    sub newopen {
        my $path = shift;
        local  *FH;  # not my!
        open   (FH, $path)          or  return undef;
        return *FH;
    }
    $fh = newopen('/etc/passwd');

الآن بعد أن أصبح لدينا تدوين *foo{THING}، لم تعد تستخدم globs الأنواع (typeglobs) بكثرة لمعالجة مقابض الملفات، رغم أنها لا تزال مطلوبة لتمرير مقابض ملفات وأدلة جديدة كليًا إلى الدوال أو منها. ذلك لأن *HANDLE{IO} لا تعمل إلا إذا كان HANDLE قد استُخدم بالفعل كمقبض. بمعنى آخر، يجب استخدام *FH لإنشاء مدخلات جديدة في جدول الرموز؛ ولا يمكن لـ *foo{THING} فعل ذلك. عند الشك، استخدم *FH.

كل الدوال القادرة على إنشاء مقابض الملفات (open()، وopendir()، وpipe()، وsocketpair()، وsysopen()، وsocket()، وaccept()) تُنشئ آليًا مقبض ملف مجهول إذا كان المقبض الممرر إليها متغيرًا سلميًا غير مُهيأ. يسمح هذا لاستخدام تراكيب مثل "open(my $fh, ...)" و "open(local $fh,...)" لإنشاء مقابض ملفات ستُغلق آليًا بشكل ملائم عند انتهاء النطاق، شريطة عدم وجود مراجع أخرى لها. يقلل هذا إلى حد كبير من الحاجة إلى typeglobs عند فتح مقابض الملفات التي يجب تمريرها، كما في المثال التالي:

    sub myopen {
        open my $fh, "@_"
             or die "Can't open '@_': $!";
        return $fh;
    }
    {
        my $f = myopen("</etc/motd");
        print <$f>;
        # $f implicitly closed here
    }

لاحظ أنه إذا استُخدم متغير عددي ممهد بدلاً من ذلك، فإن النتيجة ستختلف: "my $fh='zzz'; open($fh, ...)" تكافئ "open( *{'zzz'}, ...)". تمنع "use strict 'refs'" مثل هذه الممارسة.

طريقة أخرى لإنشاء مقابض ملفات مجهولة هي باستخدام وحدة Symbol أو وحدة IO::Handle وأمثالها. تتميز هذه الوحدات بعدم إخفاء الأنواع المختلفة للاسم نفسه أثناء local(). انظر أسفل "open" في perlfunc للحصول على مثال.

انظر أيضًا

انظر perlvar لوصف متغيرات بيرل المدمجة ومناقشة أسماء المتغيرات القانونية. انظر perlref و perlsub و "Symbol Tables" في perlmod لمزيد من النقاش حول typeglobs وصيغة *foo{THING}.

ترجمة

تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.

16 نوفمبر 2025 perl v5.40.1